Procházet zdrojové kódy

Merge pull request #15949 from ghalliday/issue27429

HPCC-27429 Add a destroy function to improve cleanup of singletons

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman před 3 roky
rodič
revize
5d783d5b52

+ 3 - 3
roxie/ccd/ccdfile.cpp

@@ -3524,12 +3524,12 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
 
 MODULE_EXIT()
 { 
-    auto cache = fileCache.queryExisting();
-    if (cache)
+    auto cleanup = [](CRoxieFileCache *cache)
     {
         cache->join();
         cache->Release();
-    }
+    };
+    fileCache.destroy(cleanup);
 }
 
 extern IRoxieFileCache &queryFileCache()

+ 1 - 1
system/jlib/jdebug.cpp

@@ -1963,7 +1963,7 @@ MODULE_INIT(INIT_PRIORITY_JDEBUG2)
 }
 MODULE_EXIT()
 {
-    delete globalOsDiskInfo.queryExisting();
+    globalOsDiskInfo.destroy();
 }
 
 const OsDiskInfo & queryGlobalOsDiskInfo()

+ 1 - 1
system/jlib/jlog.cpp

@@ -2647,7 +2647,7 @@ MODULE_EXIT()
     thePassNoneFilter = nullptr;
     thePassLocalFilter = nullptr;
     thePassAllFilter = nullptr;
-    delete logAccessor.queryExisting();
+    logAccessor.destroy([](IRemoteLogAccess * _logAccessor) { ::Release(_logAccessor); });
 }
 
 static constexpr const char * logFieldsAtt = "@fields";

+ 1 - 1
system/jlib/jmetrics.cpp

@@ -24,7 +24,7 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
 
 MODULE_EXIT()
 {
-    delete metricsManager.queryExisting();
+    metricsManager.destroy();
 }
 
 

+ 14 - 1
system/jlib/jmutex.hpp

@@ -22,6 +22,7 @@
 
 #include <assert.h>
 #include <atomic>
+#include <functional>
 #include "jiface.hpp"
 #include "jsem.hpp"
 
@@ -1002,7 +1003,19 @@ class Singleton
 {
 public:
     template <typename FUNC> X * query(FUNC factory) { return querySingleton(singleton, cs, factory); }
-    X * queryExisting() const { return singleton.load(std::memory_order_acquire); }
+
+    //destroy() is designed to be called from a static destructor, not thread safe with calls to query() ...
+    void destroy(std::function<void (X*)> destructor)
+    {
+        X * value = singleton.exchange(nullptr, std::memory_order_acq_rel);
+        if (value)
+            destructor(value);
+    }
+    void destroy()
+    {
+        X * value = singleton.exchange(nullptr, std::memory_order_acq_rel);
+        delete value;
+    }
 private:
     std::atomic<X *> singleton = {nullptr};
     CriticalSection cs;