]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: dbstore: add mechanism to signal gc_worker to exit 46023/head
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 25 Apr 2022 15:22:32 +0000 (11:22 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Wed, 27 Apr 2022 13:47:36 +0000 (09:47 -0400)
This addresses a trivial hang on shutdown.

Fixes: https://tracker.ceph.com/issues/55431
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/store/dbstore/common/dbstore.cc
src/rgw/store/dbstore/common/dbstore.h

index dfb2d6490c4fba4be75f5cba009b53c3e8e9691b..d215df6ab9558f8572de031bbea7d4d8b128c05c 100644 (file)
@@ -65,8 +65,10 @@ int DB::createGC(const DoutPrefixProvider *dpp) {
 }
 
 int DB::stopGC() {
-  if (gc_worker)
+  if (gc_worker) {
+    gc_worker->signal_stop();
     gc_worker->join();
+  }
   return 0;
 }
 
@@ -2040,6 +2042,8 @@ int DB::delete_stale_objs(const DoutPrefixProvider *dpp, const std::string& buck
 
 void *DB::GC::entry() {
   do {
+    std::unique_lock<std::mutex> lk(mtx);
+
     ldpp_dout(dpp, 2) << " DB GC started " << dendl;
     int max = 100;
     RGWUserBuckets buckets;
@@ -2071,15 +2075,18 @@ void *DB::GC::entry() {
         user_marker = user.id;
 
         /* XXX: If using locks, unlock here and reacquire in the next iteration */
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        cv.wait_for(lk, std::chrono::milliseconds(100));
+       if (stop_signalled) {
+         goto done;
+       }
       }
     } while(is_truncated);
 
     bucket_marker.clear();
-    std::this_thread::sleep_for(std::chrono::milliseconds(gc_interval*10));
-
-  } while(1);
+    cv.wait_for(lk, std::chrono::milliseconds(gc_interval*10));
+  } while(! stop_signalled);
 
+done:
   return nullptr;
 }
 
index 0779323a5daab53127569313536644a4b22785ab..10056dfa452c5235464de5ee6f81ed65859937bc 100644 (file)
@@ -9,6 +9,8 @@
 #include <string>
 #include <stdio.h>
 #include <iostream>
+#include <mutex>
+#include <condition_variable>
 // this seems safe to use, at least for now--arguably, we should
 // prefer header-only fmt, in general
 #undef FMT_HEADER_ONLY
@@ -1668,6 +1670,9 @@ class DB {
        * gc_obj_min_wait: Min. time to wait before deleting any data post its creation.
        *                    
        */
+      std::mutex mtx;
+      std::condition_variable cv;
+      bool stop_signalled = false;
       uint32_t gc_interval = 24*60*60; //sec ; default: 24*60*60
       uint32_t gc_obj_min_wait = 60*60; //60*60sec default
       std::string bucket_marker;
@@ -1678,7 +1683,13 @@ class DB {
             dpp(_dpp), db(_db) {}
 
       void *entry() override;
+
+      void signal_stop() {
+       std::lock_guard<std::mutex> lk_guard(mtx);
+       stop_signalled = true;
+       cv.notify_one();
+      }
+
       friend class DB;
     };
     std::unique_ptr<DB::GC> gc_worker;