From: Jason Dillaman Date: Tue, 13 Sep 2016 20:38:51 +0000 (-0400) Subject: librbd: helper class for quiescing in-flight async ops X-Git-Tag: v11.0.1~98^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=39d9e5cc9b38de2ee9ad2faf8e04253314160811;p=ceph.git librbd: helper class for quiescing in-flight async ops Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/Utils.h b/src/librbd/Utils.h index 6bd4320073b..b098881d6f5 100644 --- a/src/librbd/Utils.h +++ b/src/librbd/Utils.h @@ -161,6 +161,42 @@ inline ImageCtx *get_image_ctx(ImageCtx *image_ctx) { return image_ctx; } +/// helper for tracking in-flight async ops when coordinating +/// a shut down of the invoking class instance +class AsyncOpTracker { +public: + AsyncOpTracker() : m_refs(0) { + } + + void start_op() { + m_refs.inc(); + } + + void finish_op() { + if (m_refs.dec() == 0 && m_on_finish != nullptr) { + Context *on_finish = nullptr; + std::swap(on_finish, m_on_finish); + on_finish->complete(0); + } + } + + template + void wait(I &image_ctx, Context *on_finish) { + assert(m_on_finish == nullptr); + + on_finish = create_async_context_callback(image_ctx, on_finish); + if (m_refs.read() == 0) { + on_finish->complete(0); + return; + } + m_on_finish = on_finish; + } + +private: + atomic_t m_refs; + Context *m_on_finish = nullptr; +}; + } // namespace util } // namespace librbd