void AioCompletion::finish_adding_requests(CephContext *cct)
{
ldout(cct, 20) << "AioCompletion::finish_adding_requests " << (void*)this << " pending " << pending_count << dendl;
- lock.Lock();
- assert(building);
- building = false;
- if (!pending_count) {
- finalize(cct, rval);
- complete();
- }
- lock.Unlock();
+ unblock(cct);
}
int AioCompletion::wait_for_complete() {
break;
}
+ // note: possible for image to be closed after op marked finished
async_op.finish_op();
if (complete_cb) {
}
assert(pending_count);
int count = --pending_count;
- if (!count && !building) {
+ if (!count && blockers == 0) {
finalize(cct, rval);
complete();
}
void *complete_arg;
rbd_completion_t rbd_comp;
int pending_count; ///< number of requests
- bool building; ///< true if we are still building this completion
+ uint32_t blockers;
int ref;
bool released;
ImageCtx *ictx;
AioCompletion() : lock("AioCompletion::lock", true),
done(false), rval(0), complete_cb(NULL),
complete_arg(NULL), rbd_comp(NULL),
- pending_count(0), building(true),
+ pending_count(0), blockers(1),
ref(1), released(false), ictx(NULL),
aio_type(AIO_TYPE_NONE),
read_bl(NULL), read_buf(NULL), read_buf_len(0) {
if (!n)
delete this;
}
+
+ void block() {
+ Mutex::Locker l(lock);
+ ++blockers;
+ }
+ void unblock(CephContext *cct) {
+ Mutex::Locker l(lock);
+ assert(blockers > 0);
+ --blockers;
+ if (pending_count == 0 && blockers == 0) {
+ finalize(cct, rval);
+ complete();
+ }
+ }
};
class C_AioRead : public Context {