#include "common/WorkQueue.h"
#include "librbd/ImageCtx.h"
#include "librbd/Utils.h"
+#include "librbd/io/AsyncOperation.h"
#include "librbd/io/ImageDispatch.h"
#include "librbd/io/ImageDispatchInterface.h"
#include "librbd/io/ImageDispatchSpec.h"
this->register_dispatch(refresh_image_dispatch);
}
+template <typename I>
+void ImageDispatcher<I>::shut_down(Context* on_finish) {
+ // TODO ensure all IOs are executed via a dispatcher
+ // ensure read-ahead / copy-on-read ops are finished since they are
+ // currently outside dispatcher tracking
+ auto async_op = new AsyncOperation();
+
+ on_finish = new LambdaContext([this, async_op, on_finish](int r) {
+ async_op->finish_op();
+ delete async_op;
+ on_finish->complete(0);
+ });
+ on_finish = new LambdaContext([this, async_op, on_finish](int r) {
+ async_op->start_op(*this->m_image_ctx);
+ async_op->flush(on_finish);
+ });
+ Dispatcher<I, ImageDispatcherInterface>::shut_down(on_finish);
+}
+
template <typename I>
void ImageDispatcher<I>::apply_qos_schedule_tick_min(uint64_t tick) {
m_qos_image_dispatch->apply_qos_schedule_tick_min(tick);
public:
ImageDispatcher(ImageCtxT* image_ctx);
+ void shut_down(Context* on_finish) override;
+
void apply_qos_schedule_tick_min(uint64_t tick) override;
void apply_qos_limit(uint64_t flag, uint64_t limit, uint64_t burst) override;
: MockImageCtx(image_ctx) {
parent = mock_parent_image_ctx;
}
+ ~MockTestImageCtx() override {
+ // copyups need to complete prior to attempting to delete this object
+ wait_for_async_ops();
+ }
std::map<uint64_t, librbd::io::CopyupRequest<librbd::MockTestImageCtx>*> copyup_list;
};
#include "test/librbd/mock/MockImageCtx.h"
#include "test/librbd/mock/MockSafeTimer.h"
+#include "librbd/io/AsyncOperation.h"
static MockSafeTimer *s_timer;
static ceph::mutex *s_timer_lock;
*timer_lock = s_timer_lock;
}
+void MockImageCtx::wait_for_async_ops() {
+ io::AsyncOperation async_op;
+ async_op.start_op(*image_ctx);
+
+ C_SaferCond ctx;
+ async_op.flush(&ctx);
+ ctx.wait();
+
+ async_op.finish_op();
+}
+
} // namespace librbd
}
}
- ~MockImageCtx() {
+ virtual ~MockImageCtx() {
wait_for_async_requests();
+ wait_for_async_ops();
image_ctx->md_ctx.aio_flush();
image_ctx->data_ctx.aio_flush();
image_ctx->op_work_queue->drain();
delete io_object_dispatcher;
}
+ void wait_for_async_ops();
void wait_for_async_requests() {
async_ops_lock.lock();
if (async_requests.empty()) {