]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
TaskFinisher: cancel all tasks wait until finisher done 9682/head
authorHaomai Wang <haomai@xsky.com>
Tue, 14 Jun 2016 03:03:19 +0000 (11:03 +0800)
committerHaomai Wang <haomai@xsky.com>
Wed, 15 Jun 2016 14:24:37 +0000 (22:24 +0800)
Otherwise, caller may think pending task won't be executed but actually
finisher may execute callback which may cause refer to freed object.

Signed-off-by: Haomai Wang <haomai@xsky.com>
src/librbd/ImageWatcher.cc
src/librbd/TaskFinisher.h

index d3d4e701a736ee92c2c7e7192c62b337910e34b2..9cd643c68f3abc85b9116bf1c84ffa514a8deb48 100644 (file)
@@ -31,6 +31,7 @@ namespace librbd {
 
 using namespace image_watcher;
 using namespace watch_notify;
+using util::create_async_context_callback;
 using util::create_context_callback;
 using util::create_rados_safe_callback;
 
@@ -120,7 +121,10 @@ void ImageWatcher::unregister_watch(Context *on_finish) {
   ldout(m_image_ctx.cct, 10) << this << " unregistering image watcher" << dendl;
 
   cancel_async_requests();
-  m_task_finisher->cancel_all();
+
+  C_Gather *g = new C_Gather(m_image_ctx.cct, create_async_context_callback(
+          m_image_ctx, on_finish));
+  m_task_finisher->cancel_all(g->new_sub());
 
   {
     RWLock::WLocker l(m_watch_lock);
@@ -128,17 +132,17 @@ void ImageWatcher::unregister_watch(Context *on_finish) {
       m_watch_state = WATCH_STATE_UNREGISTERED;
 
       librados::AioCompletion *aio_comp = create_rados_safe_callback(
-        new C_UnwatchAndFlush(m_image_ctx.md_ctx, on_finish));
+        new C_UnwatchAndFlush(m_image_ctx.md_ctx, g->new_sub()));
       int r = m_image_ctx.md_ctx.aio_unwatch(m_watch_handle, aio_comp);
       assert(r == 0);
       aio_comp->release();
+      g->activate();
       return;
     } else if (m_watch_state == WATCH_STATE_ERROR) {
       m_watch_state = WATCH_STATE_UNREGISTERED;
     }
   }
-
-  on_finish->complete(0);
+  g->activate();
 }
 
 void ImageWatcher::flush(Context *on_finish) {
index 466537e727375a4d79eee5845fe353b89600dbd3..f54681f4bb96e68190bb6fd0b7413fb2f519b6f1 100644 (file)
@@ -63,13 +63,17 @@ public:
     }
   }
 
-  void cancel_all() {
-    Mutex::Locker l(*m_lock);
-    for (typename TaskContexts::iterator it = m_task_contexts.begin();
-         it != m_task_contexts.end(); ++it) {
-      delete it->second.first;
+  void cancel_all(Context *comp) {
+    {
+      Mutex::Locker l(*m_lock);
+      for (typename TaskContexts::iterator it = m_task_contexts.begin();
+           it != m_task_contexts.end(); ++it) {
+        delete it->second.first;
+        m_safe_timer->cancel_event(it->second.second);
+      }
+      m_task_contexts.clear();
     }
-    m_task_contexts.clear();
+    m_finisher->queue(comp);
   }
 
   bool add_event_after(const Task& task, double seconds, Context *ctx) {