MagickCore 6.9.13
Loading...
Searching...
No Matches
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 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*/
49typedef struct _MagickThreadValue
50{
51 size_t
52 number_threads;
53
54 void
55 **values,
56 (*destructor)(void *);
58
59/* Deprecated */
60MagickExport 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 */
74MagickExport 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 */
87MagickExport 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 */
99MagickExport 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*/
137MagickExport 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=(void **) AcquireQuantumMemory((*keys)->number_threads,
157 sizeof(void *));
158 if ((*keys)->values == (void **) NULL)
159 *keys=(MagickThreadValue *) 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*/
192MagickExport 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*/
243MagickExport 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*/
286MagickExport 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}