diff options
Diffstat (limited to 'src/librbd/AsyncRequest.cc')
-rw-r--r-- | src/librbd/AsyncRequest.cc | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/librbd/AsyncRequest.cc b/src/librbd/AsyncRequest.cc new file mode 100644 index 00000000..8a76a226 --- /dev/null +++ b/src/librbd/AsyncRequest.cc @@ -0,0 +1,71 @@ +// -*- 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 <typename T> +AsyncRequest<T>::AsyncRequest(T &image_ctx, Context *on_finish) + : m_image_ctx(image_ctx), m_on_finish(on_finish), m_canceled(false), + m_xlist_item(this) { + ceph_assert(m_on_finish != NULL); + start_request(); +} + +template <typename T> +AsyncRequest<T>::~AsyncRequest() { +} + +template <typename T> +void AsyncRequest<T>::async_complete(int r) { + m_image_ctx.op_work_queue->queue(create_callback_context(), r); +} + +template <typename T> +librados::AioCompletion *AsyncRequest<T>::create_callback_completion() { + return util::create_rados_callback(this); +} + +template <typename T> +Context *AsyncRequest<T>::create_callback_context() { + return util::create_context_callback(this); +} + +template <typename T> +Context *AsyncRequest<T>::create_async_callback_context() { + return util::create_context_callback<AsyncRequest<T>, + &AsyncRequest<T>::async_complete>(this); +} + +template <typename T> +void AsyncRequest<T>::start_request() { + Mutex::Locker async_ops_locker(m_image_ctx.async_ops_lock); + m_image_ctx.async_requests.push_back(&m_xlist_item); +} + +template <typename T> +void AsyncRequest<T>::finish_request() { + decltype(m_image_ctx.async_requests_waiters) waiters; + { + Mutex::Locker async_ops_locker(m_image_ctx.async_ops_lock); + ceph_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<librbd::ImageCtx>; +#endif |