Add an already-locked helper so that C_Aio{Safe,Complete} can
increment the reference count when their caller holds the
lock. C_AioCompleteAndSafe's caller is not holding the lock, so call
regular get() to ensure no racing updates can occur.
This eliminates all direct manipulations of AioCompletionImpl->ref,
and makes the necessary locking clear.
The only place C_AioCompleteAndSafe is used is in handling
aio_flush_async(). This could cause a missing completion.
Refs: #5919
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Tested-by: Oliver Francke <Oliver.Francke@filoo.de>
(cherry picked from commit
7a52e2ff5025754f3040eff3fc52d4893cafc389)
void get() {
lock.Lock();
- assert(ref > 0);
- ref++;
+ _get();
lock.Unlock();
}
+ void _get() {
+ assert(lock.is_locked());
+ assert(ref > 0);
+ ++ref;
+ }
void release() {
lock.Lock();
assert(!released);
AioCompletionImpl *c;
C_AioComplete(AioCompletionImpl *cc) : c(cc) {
- c->ref++;
+ c->_get();
}
void finish(int r) {
AioCompletionImpl *c;
C_AioSafe(AioCompletionImpl *cc) : c(cc) {
- c->ref++;
+ c->_get();
}
void finish(int r) {
AioCompletionImpl *c;
C_AioCompleteAndSafe(AioCompletionImpl *cc) : c(cc) {
- c->ref++;
+ c->get();
}
void finish(int r) {