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 QtShaderTools { |
45 | namespace glslang { |
46 | |
47 | OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX; |
48 | |
49 | // Per-process initialization. |
50 | // Needs to be called at least once before parsing, etc. is done. |
51 | // Will also do thread initialization for the calling thread; other |
52 | // threads will need to do that explicitly. |
53 | bool InitProcess() |
54 | { |
55 | glslang::GetGlobalLock(); |
56 | |
57 | if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) { |
58 | // |
59 | // Function is re-entrant. |
60 | // |
61 | |
62 | glslang::ReleaseGlobalLock(); |
63 | return true; |
64 | } |
65 | |
66 | ThreadInitializeIndex = OS_AllocTLSIndex(); |
67 | |
68 | if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { |
69 | assert(0 && "InitProcess(): Failed to allocate TLS area for init flag" ); |
70 | |
71 | glslang::ReleaseGlobalLock(); |
72 | return false; |
73 | } |
74 | |
75 | if (! InitializePoolIndex()) { |
76 | assert(0 && "InitProcess(): Failed to initialize global pool" ); |
77 | |
78 | glslang::ReleaseGlobalLock(); |
79 | return false; |
80 | } |
81 | |
82 | if (! InitThread()) { |
83 | assert(0 && "InitProcess(): Failed to initialize thread" ); |
84 | |
85 | glslang::ReleaseGlobalLock(); |
86 | return false; |
87 | } |
88 | |
89 | glslang::ReleaseGlobalLock(); |
90 | return true; |
91 | } |
92 | |
93 | // Per-thread scoped initialization. |
94 | // Must be called at least once by each new thread sharing the |
95 | // symbol tables, etc., needed to parse. |
96 | bool InitThread() |
97 | { |
98 | // |
99 | // This function is re-entrant |
100 | // |
101 | if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { |
102 | assert(0 && "InitThread(): Process hasn't been initalised." ); |
103 | return false; |
104 | } |
105 | |
106 | if (OS_GetTLSValue(nIndex: ThreadInitializeIndex) != 0) |
107 | return true; |
108 | |
109 | if (! OS_SetTLSValue(nIndex: ThreadInitializeIndex, lpvValue: (void *)1)) { |
110 | assert(0 && "InitThread(): Unable to set init flag." ); |
111 | return false; |
112 | } |
113 | |
114 | glslang::SetThreadPoolAllocator(nullptr); |
115 | |
116 | return true; |
117 | } |
118 | |
119 | // Not necessary to call this: InitThread() is reentrant, and the need |
120 | // to do per thread tear down has been removed. |
121 | // |
122 | // This is kept, with memory management removed, to satisfy any exiting |
123 | // calls to it that rely on it. |
124 | bool DetachThread() |
125 | { |
126 | bool success = true; |
127 | |
128 | if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) |
129 | return true; |
130 | |
131 | // |
132 | // Function is re-entrant and this thread may not have been initialized. |
133 | // |
134 | if (OS_GetTLSValue(nIndex: ThreadInitializeIndex) != 0) { |
135 | if (!OS_SetTLSValue(nIndex: ThreadInitializeIndex, lpvValue: (void *)0)) { |
136 | assert(0 && "DetachThread(): Unable to clear init flag." ); |
137 | success = false; |
138 | } |
139 | } |
140 | |
141 | return success; |
142 | } |
143 | |
144 | // Not necessary to call this: InitProcess() is reentrant. |
145 | // |
146 | // This is kept, with memory management removed, to satisfy any exiting |
147 | // calls to it that rely on it. |
148 | // |
149 | // Users of glslang should call shFinalize() or glslang::FinalizeProcess() for |
150 | // process-scoped memory tear down. |
151 | bool DetachProcess() |
152 | { |
153 | bool success = true; |
154 | |
155 | if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) |
156 | return true; |
157 | |
158 | success = DetachThread(); |
159 | |
160 | OS_FreeTLSIndex(nIndex: ThreadInitializeIndex); |
161 | ThreadInitializeIndex = OS_INVALID_TLS_INDEX; |
162 | |
163 | return success; |
164 | } |
165 | |
166 | } // end namespace glslang |
167 | } // namespace QtShaderTools |
168 | |