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. |
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. |
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) != nullptr) |
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. |
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) != nullptr) { |
134 | if (!OS_SetTLSValue(ThreadInitializeIndex, nullptr)) { |
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. |
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 | |