Memory: Reference count number of clients, to support multiple independent clients...
authorJohn Kessenich <cepheus@frii.com>
Fri, 17 Nov 2017 05:48:41 +0000 (22:48 -0700)
committerJohn Kessenich <cepheus@frii.com>
Fri, 17 Nov 2017 06:02:14 +0000 (23:02 -0700)
Addresses 2nd item in #976.

StandAlone/StandAlone.cpp
glslang/MachineIndependent/ShaderLang.cpp

index 3abc8b51cd0380f186ee9db613442445d420db6f..e7844eb21f6eb548f21368d38662c6dd689659ce 100644 (file)
@@ -1074,21 +1074,24 @@ int singleMain()
     if (Options & EOptionLinkProgram ||
         Options & EOptionOutputPreprocessed) {
         glslang::InitializeProcess();
+        glslang::InitializeProcess();  // also test reference counting of users
+        glslang::InitializeProcess();  // also test reference counting of users
+        glslang::FinalizeProcess();    // also test reference counting of users
+        glslang::FinalizeProcess();    // also test reference counting of users
         CompileAndLinkShaderFiles(workList);
         glslang::FinalizeProcess();
     } else {
         ShInitialize();
+        ShInitialize();  // also test reference counting of users
+        ShFinalize();    // also test reference counting of users
 
         bool printShaderNames = workList.size() > 1;
 
-        if (Options & EOptionMultiThreaded)
-        {
+        if (Options & EOptionMultiThreaded) {
             std::array<std::thread, 16> threads;
-            for (unsigned int t = 0; t < threads.size(); ++t)
-            {
+            for (unsigned int t = 0; t < threads.size(); ++t) {
                 threads[t] = std::thread(CompileShaders, std::ref(workList));
-                if (threads[t].get_id() == std::thread::id())
-                {
+                if (threads[t].get_id() == std::thread::id()) {
                     fprintf(stderr, "Failed to create thread\n");
                     return EFailThreadCreate;
                 }
index ec5327d9ce384bd4bbe5454a0f84f6231721985c..62e079e5567ae1de883ccd1e9447556728108051 100644 (file)
 
 namespace { // anonymous namespace for file-local functions and symbols
 
+// Total number of successful initializers of glslang: a refcount
+// Shared global; access should be protected by a global mutex/critical section.
+int NumberOfClients = 0;
+
 using namespace glslang;
 
 // Create a language specific version of parseables.
@@ -1193,6 +1197,10 @@ int ShInitialize()
     if (! InitProcess())
         return 0;
 
+    glslang::GetGlobalLock();
+    ++NumberOfClients;
+    glslang::ReleaseGlobalLock();
+
     if (PerProcessGPA == nullptr)
         PerProcessGPA = new TPoolAllocator();
 
@@ -1259,6 +1267,14 @@ void ShDestruct(ShHandle handle)
 //
 int __fastcall ShFinalize()
 {
+    glslang::GetGlobalLock();
+    --NumberOfClients;
+    assert(NumberOfClients >= 0);
+    bool finalize = NumberOfClients == 0;
+    glslang::ReleaseGlobalLock();
+    if (! finalize)
+        return 1;
+
     for (int version = 0; version < VersionCount; ++version) {
         for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
             for (int p = 0; p < ProfileCount; ++p) {