1 //
2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 //
9 // Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 //
17 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 // POSSIBILITY OF SUCH DAMAGE.
33 //
34
35 #define SH_EXPORTING
36
37 #include <cassert>
38
39 #include "InitializeDll.h"
40 #include "../glslang/Include/InitializeGlobals.h"
41 #include "../glslang/Public/ShaderLang.h"
42 #include "../glslang/Include/PoolAlloc.h"
43
44 namespace glslang {
45
46 OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
47
48 // Per-process initialization.
49 // Needs to be called at least once before parsing, etc. is done.
50 // Will also do thread initialization for the calling thread; other
51 // threads will need to do that explicitly.
InitProcess()52 bool InitProcess()
53 {
54 glslang::GetGlobalLock();
55
56 if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
57 //
58 // Function is re-entrant.
59 //
60
61 glslang::ReleaseGlobalLock();
62 return true;
63 }
64
65 ThreadInitializeIndex = OS_AllocTLSIndex();
66
67 if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
68 assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
69
70 glslang::ReleaseGlobalLock();
71 return false;
72 }
73
74 if (! InitializePoolIndex()) {
75 assert(0 && "InitProcess(): Failed to initialize global pool");
76
77 glslang::ReleaseGlobalLock();
78 return false;
79 }
80
81 if (! InitThread()) {
82 assert(0 && "InitProcess(): Failed to initialize thread");
83
84 glslang::ReleaseGlobalLock();
85 return false;
86 }
87
88 glslang::ReleaseGlobalLock();
89 return true;
90 }
91
92 // Per-thread scoped initialization.
93 // Must be called at least once by each new thread sharing the
94 // symbol tables, etc., needed to parse.
InitThread()95 bool InitThread()
96 {
97 //
98 // This function is re-entrant
99 //
100 if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
101 assert(0 && "InitThread(): Process hasn't been initalised.");
102 return false;
103 }
104
105 if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
106 return true;
107
108 if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
109 assert(0 && "InitThread(): Unable to set init flag.");
110 return false;
111 }
112
113 glslang::SetThreadPoolAllocator(nullptr);
114
115 return true;
116 }
117
118 // Not necessary to call this: InitThread() is reentrant, and the need
119 // to do per thread tear down has been removed.
120 //
121 // This is kept, with memory management removed, to satisfy any exiting
122 // calls to it that rely on it.
DetachThread()123 bool DetachThread()
124 {
125 bool success = true;
126
127 if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
128 return true;
129
130 //
131 // Function is re-entrant and this thread may not have been initialized.
132 //
133 if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
134 if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
135 assert(0 && "DetachThread(): Unable to clear init flag.");
136 success = false;
137 }
138 }
139
140 return success;
141 }
142
143 // Not necessary to call this: InitProcess() is reentrant.
144 //
145 // This is kept, with memory management removed, to satisfy any exiting
146 // calls to it that rely on it.
147 //
148 // Users of glslang should call shFinalize() or glslang::FinalizeProcess() for
149 // process-scoped memory tear down.
DetachProcess()150 bool DetachProcess()
151 {
152 bool success = true;
153
154 if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
155 return true;
156
157 success = DetachThread();
158
159 OS_FreeTLSIndex(ThreadInitializeIndex);
160 ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
161
162 return success;
163 }
164
165 } // end namespace glslang
166