// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #include "librbd/AsyncRequest.h" #include "librbd/ImageCtx.h" #include "librbd/Utils.h" #include "common/WorkQueue.h" namespace librbd { template AsyncRequest::AsyncRequest(T &image_ctx, Context *on_finish) : m_image_ctx(image_ctx), m_on_finish(on_finish), m_canceled(false), m_xlist_item(this) { assert(m_on_finish != NULL); start_request(); } template AsyncRequest::~AsyncRequest() { } template void AsyncRequest::async_complete(int r) { m_image_ctx.op_work_queue->queue(create_callback_context(), r); } template librados::AioCompletion *AsyncRequest::create_callback_completion() { return util::create_rados_callback(this); } template Context *AsyncRequest::create_callback_context() { return util::create_context_callback(this); } template Context *AsyncRequest::create_async_callback_context() { return util::create_context_callback, &AsyncRequest::async_complete>(this); } template void AsyncRequest::start_request() { Mutex::Locker async_ops_locker(m_image_ctx.async_ops_lock); m_image_ctx.async_requests.push_back(&m_xlist_item); } template void AsyncRequest::finish_request() { decltype(m_image_ctx.async_requests_waiters) waiters; { Mutex::Locker async_ops_locker(m_image_ctx.async_ops_lock); assert(m_xlist_item.remove_myself()); if (m_image_ctx.async_requests.empty()) { waiters = std::move(m_image_ctx.async_requests_waiters); } } for (auto ctx : waiters) { ctx->complete(0); } } } // namespace librbd #ifndef TEST_F template class librbd::AsyncRequest; #endif