int AioCompletion::wait_for_complete() {
tracepoint(librbd, aio_wait_for_complete_enter, this);
lock.Lock();
- while (!done)
+ while (state != STATE_COMPLETE)
cond.Wait(lock);
lock.Unlock();
tracepoint(librbd, aio_wait_for_complete_exit, 0);
ictx->journal->commit_io_event(journal_tid, rval);
}
- done = true;
+ state = STATE_CALLBACK;
if (complete_cb) {
lock.Unlock();
complete_cb(rbd_comp, complete_arg);
ictx->completed_reqs_lock.Unlock();
ictx->event_socket.notify();
}
+
+ state = STATE_COMPLETE;
cond.Signal();
// note: possible for image to be closed after op marked finished
init_time(i, t);
Mutex::Locker locker(lock);
- if (!done && !async_op.started()) {
+ if (state == STATE_PENDING && !async_op.started()) {
async_op.start_op(*ictx);
}
}
void AioCompletion::associate_journal_event(uint64_t tid) {
Mutex::Locker l(lock);
- assert(!done);
+ assert(state == STATE_PENDING);
journal_tid = tid;
}
bool done;
{
Mutex::Locker l(lock);
- done = this->done;
+ done = this->state == STATE_COMPLETE;
}
tracepoint(librbd, aio_is_complete_exit, done);
return done;
AIO_TYPE_FLUSH,
} aio_type_t;
+ typedef enum {
+ STATE_PENDING = 0,
+ STATE_CALLBACK,
+ STATE_COMPLETE,
+ } aio_state_t;
+
/**
* AioCompletion is the overall completion for a single
* rbd I/O request. It may be composed of many AioObjectRequests,
struct AioCompletion {
Mutex lock;
Cond cond;
- bool done;
+ aio_state_t state;
ssize_t rval;
callback_t complete_cb;
void *complete_arg;
}
AioCompletion() : lock("AioCompletion::lock", true, false),
- done(false), rval(0), complete_cb(NULL),
+ state(STATE_PENDING), rval(0), complete_cb(NULL),
complete_arg(NULL), rbd_comp(NULL),
pending_count(0), blockers(1),
ref(1), released(false), ictx(NULL),