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;
}
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.
if (! InitProcess())
return 0;
+ glslang::GetGlobalLock();
+ ++NumberOfClients;
+ glslang::ReleaseGlobalLock();
+
if (PerProcessGPA == nullptr)
PerProcessGPA = new TPoolAllocator();
//
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) {