MagickCore  6.9.12-67
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
thread.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % TTTTT H H RRRR EEEEE AAA DDDD %
6 % T H H R R E A A D D %
7 % T HHHHH RRRR EEE AAAAA D D %
8 % T H H R R E A A D D %
9 % T H H R R EEEEE A A DDDD %
10 % %
11 % %
12 % MagickCore Thread Methods %
13 % %
14 % Software Design %
15 % Cristy %
16 % March 2003 %
17 % %
18 % %
19 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 
38 /*
39  Include declarations.
40 */
41 #include "magick/studio.h"
42 #include "magick/memory_.h"
43 #include "magick/thread_.h"
44 #include "magick/thread-private.h"
45 
46 /*
47  Typedef declarations.
48 */
49 typedef struct _MagickThreadValue
50 {
51  size_t
52  number_threads;
53 
54  void
55  **values,
56  (*destructor)(void *);
58 
59 /* Deprecated */
60 MagickExport MagickBooleanType MagickCreateThreadKey(MagickThreadKey *key)
61 {
62 #if defined(MAGICKCORE_THREAD_SUPPORT)
63  return(pthread_key_create(key,NULL) == 0 ? MagickTrue : MagickFalse);
64 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
65  *key=TlsAlloc();
66  return(*key != TLS_OUT_OF_INDEXES ? MagickTrue : MagickFalse);
67 #else
68  *key=AcquireMagickMemory(sizeof(key));
69  return(*key != (void *) NULL ? MagickTrue : MagickFalse);
70 #endif
71 }
72 
73 /* Deprecated */
74 MagickExport MagickBooleanType MagickDeleteThreadKey(MagickThreadKey key)
75 {
76 #if defined(MAGICKCORE_THREAD_SUPPORT)
77  return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse);
78 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
79  return(TlsFree(key) != 0 ? MagickTrue : MagickFalse);
80 #else
81  key=(MagickThreadKey) RelinquishMagickMemory(key);
82  return(MagickTrue);
83 #endif
84 }
85 
86 /* Deprecated */
87 MagickExport void *MagickGetThreadValue(MagickThreadKey key)
88 {
89 #if defined(MAGICKCORE_THREAD_SUPPORT)
90  return(pthread_getspecific(key));
91 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
92  return(TlsGetValue(key));
93 #else
94  return((void *) key);
95 #endif
96 }
97 
98 /* Deprecated */
99 MagickExport MagickBooleanType MagickSetThreadValue(MagickThreadKey key,
100  const void *value)
101 {
102 #if defined(MAGICKCORE_THREAD_SUPPORT)
103  return(pthread_setspecific(key,value) == 0 ? MagickTrue : MagickFalse);
104 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
105  return(TlsSetValue(key,(void *) value) != 0 ? MagickTrue : MagickFalse);
106 #else
107  key=(void *) value;
108  return(MagickTrue);
109 #endif
110 }
111 
112 /*
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 % %
115 % %
116 % %
117 % C r e a t e M a g i c k T h r e a d K e y %
118 % %
119 % %
120 % %
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 %
123 % CreateMagickThreadKey() creates a thread-specific data key visible to all
124 % threads in the process.
125 %
126 % The format of the CreateMagickThreadKey method is:
127 %
128 % MagickThreadKey CreateMagickThreadKey(MagickThreadKey *key)
129 %
130 % A description of each parameter follows:
131 %
132 % o key: opaque objects used to locate thread-specific data.
133 %
134 % o destructor: associate an optional destructor with each key value.
135 %
136 */
137 MagickExport MagickBooleanType CreateMagickThreadKey(MagickThreadKey *key,
138  void (*destructor)(void *))
139 {
140 #if defined(MAGICKCORE_THREAD_SUPPORT)
141  return(pthread_key_create(key,destructor) == 0 ? MagickTrue : MagickFalse);
142 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
143  magick_unreferenced(destructor);
144  *key=TlsAlloc();
145  return(*key != TLS_OUT_OF_INDEXES ? MagickTrue : MagickFalse);
146 #else
147  {
149  **keys;
150 
151  keys=(MagickThreadValue **) key;
152  *keys=(MagickThreadValue *) AcquireMagickMemory(sizeof(**keys));
153  if (*keys != (MagickThreadValue *) NULL)
154  {
155  (*keys)->number_threads=GetOpenMPMaximumThreads();
156  (*keys)->values=AcquireQuantumMemory((*keys)->number_threads,
157  sizeof(void *));
158  if ((*keys)->values == (void *) NULL)
159  *keys=RelinquishMagickMemory(*keys);
160  else
161  (void) memset((*keys)->values,0,(*keys)->number_threads*
162  sizeof(void *));
163  (*keys)->destructor=destructor;
164  }
165  return((*keys != (MagickThreadValue *) NULL) ? MagickTrue : MagickFalse);
166  }
167 #endif
168 }
169 
170 /*
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % %
173 % %
174 % %
175 % D e l e t e M a g i c k T h r e a d K e y %
176 % %
177 % %
178 % %
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 %
181 % DeleteMagickThreadKey() deletes a thread-specific data key.
182 %
183 % The format of the DeleteMagickThreadKey method is:
184 %
185 % MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
186 %
187 % A description of each parameter follows:
188 %
189 % o key: the thread key.
190 %
191 */
192 MagickExport MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
193 {
194 #if defined(MAGICKCORE_THREAD_SUPPORT)
195  return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse);
196 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
197  return(TlsFree(key) != 0 ? MagickTrue : MagickFalse);
198 #else
199  {
201  *keys;
202 
203  ssize_t
204  i;
205 
206  keys=(MagickThreadValue *) key;
207  for (i=0; i < (ssize_t) keys->number_threads; i++)
208  if ((keys->destructor != (void *) NULL) &&
209  (keys->values[i] != (void *) NULL))
210  {
211  keys->destructor(keys->values[i]);
212  keys->values[i]=(void *) NULL;
213  }
214  keys=(MagickThreadValue *) RelinquishMagickMemory(keys);
215  }
216  return(MagickTrue);
217 #endif
218 }
219 
220 /*
221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % %
223 % %
224 % %
225 % G e t M a g i c k T h r e a d V a l u e %
226 % %
227 % %
228 % %
229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 %
231 % GetMagickThreadValue() returns the value currently bound to the specified
232 % key on behalf of the calling thread.
233 %
234 % The format of the GetMagickThreadValue method is:
235 %
236 % void *GetMagickThreadValue(MagickThreadKey key)
237 %
238 % A description of each parameter follows:
239 %
240 % o key: the thread key.
241 %
242 */
243 MagickExport void *GetMagickThreadValue(MagickThreadKey key)
244 {
245 #if defined(MAGICKCORE_THREAD_SUPPORT)
246  return(pthread_getspecific(key));
247 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
248  return(TlsGetValue(key));
249 #else
250  {
252  *keys;
253 
254  keys=(MagickThreadValue *) key;
255  return(keys->values[GetOpenMPThreadId()]);
256  }
257 #endif
258 }
259 
260 /*
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262 % %
263 % %
264 % %
265 % S e t M a g i c k T h r e a d V a l u e %
266 % %
267 % %
268 % %
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 %
271 % SetMagickThreadValue() binds a value to the specified key on behalf of the
272 % calling thread.
273 %
274 % The format of the SetMagickThreadValue method is:
275 %
276 % MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
277 % const void *value)
278 %
279 % A description of each parameter follows:
280 %
281 % o key: the thread key.
282 %
283 % o value: the value.
284 %
285 */
286 MagickExport MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
287  const void *value)
288 {
289 #if defined(MAGICKCORE_THREAD_SUPPORT)
290  return(pthread_setspecific(key,value) == 0 ? MagickTrue : MagickFalse);
291 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
292  return(TlsSetValue(key,(void *) value) != 0 ? MagickTrue : MagickFalse);
293 #else
294  {
296  *keys;
297 
298  keys=(MagickThreadValue *) key;
299  keys->values[GetOpenMPThreadId()]=(void *) value;
300  }
301  return(MagickTrue);
302 #endif
303 }