Explorar el Código

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

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday hace 3 años
padre
commit
c95dcb86ba
Se han modificado 5 ficheros con 20 adiciones y 7 borrados
  1. 3 3
      roxie/ccd/ccdfile.cpp
  2. 1 1
      system/jlib/jdebug.cpp
  3. 1 1
      system/jlib/jlog.cpp
  4. 1 1
      system/jlib/jmetrics.cpp
  5. 14 1
      system/jlib/jmutex.hpp

+ 3 - 3
roxie/ccd/ccdfile.cpp

@@ -3523,12 +3523,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;