]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: fix waiting for module shutdown() before destroying
authorJohn Spray <john.spray@redhat.com>
Wed, 29 Mar 2017 17:34:29 +0000 (13:34 -0400)
committerJohn Spray <john.spray@redhat.com>
Thu, 20 Apr 2017 14:00:30 +0000 (15:00 +0100)
Fixes: http://tracker.ceph.com/issues/19412
Signed-off-by: John Spray <john.spray@redhat.com>
src/mgr/PyModules.cc

index 6bb5384ec9bea31f718d742f15d966ed17796410..33cb6264c38a5d820f311eeec460ee124eb988c4 100644 (file)
@@ -446,20 +446,39 @@ void PyModules::shutdown()
 {
   Mutex::Locker locker(lock);
 
-  // Signal modules to drop out of serve()
-  for (auto& i : modules) {
+  // Signal modules to drop out of serve() and/or tear down resources
+  C_SaferCond shutdown_called;
+  C_GatherBuilder gather(g_ceph_context);
+  for (auto &i : modules) {
     auto module = i.second.get();
-    finisher.queue(new FunctionContext([module](int r){
+    auto shutdown_cb = gather.new_sub();
+    finisher.queue(new FunctionContext([module, shutdown_cb](int r){
       module->shutdown();
+      shutdown_cb->complete(0);
     }));
   }
 
+  if (gather.has_subs()) {
+    gather.set_finisher(&shutdown_called);
+    gather.activate();
+  }
+
+  // For modules implementing serve(), finish the threads where we
+  // were running that.
   for (auto &i : serve_threads) {
     lock.Unlock();
     i.second->join();
     lock.Lock();
   }
   serve_threads.clear();
+
+  // Wait for the module's shutdown() to complete before
+  // we proceed to destroy the module.
+  if (!modules.empty()) {
+    dout(4) << "waiting for module shutdown calls" << dendl;
+    shutdown_called.wait();
+  }
+
   modules.clear();
 
   PyGILState_Ensure();