2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
12 % MagickCore Thread Methods %
19 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % https://www.imagemagick.org/script/license.php %
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. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 #include "MagickCore/studio.h"
42 #include "MagickCore/memory_.h"
43 #include "MagickCore/thread_.h"
44 #include "MagickCore/thread-private.h"
49 typedef struct _MagickThreadValue
56 (*destructor)(void *);
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 % C r e a t e M a g i c k T h r e a d K e y %
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 % CreateMagickThreadKey() creates a thread-specific data key visible to all
71 % threads in the process.
73 % The format of the CreateMagickThreadKey method is:
75 % MagickThreadKey CreateMagickThreadKey(MagickThreadKey *key)
77 % A description of each parameter follows:
79 % o key: opaque objects used to locate thread-specific data.
81 % o destructor: associate an optional destructor with each key value.
84 MagickExport MagickBooleanType CreateMagickThreadKey(MagickThreadKey *key,
85 void (*destructor)(void *))
87 #if defined(MAGICKCORE_THREAD_SUPPORT)
88 return(pthread_key_create(key,destructor) == 0 ? MagickTrue : MagickFalse);
89 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
90 magick_unreferenced(destructor);
92 return(*key != TLS_OUT_OF_INDEXES ? MagickTrue : MagickFalse);
98 keys=(MagickThreadValue **) key;
99 *keys=(MagickThreadValue *) AcquireQuantumMemory(1,sizeof(**keys));
100 if (*keys != (MagickThreadValue *) NULL)
102 (*keys)->number_threads=GetOpenMPMaximumThreads();
103 (*keys)->values=AcquireQuantumMemory((*keys)->number_threads,
105 if ((*keys)->values == (void *) NULL)
106 *keys=RelinquishMagickMemory(*keys);
108 (void) memset((*keys)->values,0,(*keys)->number_threads*
110 (*keys)->destructor=destructor;
112 return((*keys != (MagickThreadValue *) NULL) ? MagickTrue : MagickFalse);
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 % D e l e t e M a g i c k T h r e a d K e y %
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % DeleteMagickThreadKey() deletes a thread-specific data key.
130 % The format of the DeleteMagickThreadKey method is:
132 % MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
134 % A description of each parameter follows:
136 % o key: the thread key.
139 MagickExport MagickBooleanType DeleteMagickThreadKey(MagickThreadKey key)
141 #if defined(MAGICKCORE_THREAD_SUPPORT)
142 return(pthread_key_delete(key) == 0 ? MagickTrue : MagickFalse);
143 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
144 return(TlsFree(key) != 0 ? MagickTrue : MagickFalse);
153 keys=(MagickThreadValue *) key;
154 for (i=0; i < (ssize_t) keys->number_threads; i++)
155 if ((keys->destructor != (void *) NULL) &&
156 (keys->values[i] != (void *) NULL))
158 keys->destructor(keys->values[i]);
159 keys->values[i]=(void *) NULL;
161 keys=(MagickThreadValue *) RelinquishMagickMemory(keys);
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % G e t M a g i c k T h r e a d V a l u e %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 % GetMagickThreadValue() returns the value currently bound to the specified
179 % key on behalf of the calling thread.
181 % The format of the GetMagickThreadValue method is:
183 % void *GetMagickThreadValue(MagickThreadKey key)
185 % A description of each parameter follows:
187 % o key: the thread key.
190 MagickExport void *GetMagickThreadValue(MagickThreadKey key)
192 #if defined(MAGICKCORE_THREAD_SUPPORT)
193 return(pthread_getspecific(key));
194 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
195 return(TlsGetValue(key));
201 keys=(MagickThreadValue *) key;
202 return(keys->values[GetOpenMPThreadId()]);
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212 % S e t M a g i c k T h r e a d V a l u e %
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 % SetMagickThreadValue() binds a value to the specified key on behalf of the
221 % The format of the SetMagickThreadValue method is:
223 % MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
226 % A description of each parameter follows:
228 % o key: the thread key.
230 % o value: the value.
233 MagickExport MagickBooleanType SetMagickThreadValue(MagickThreadKey key,
236 #if defined(MAGICKCORE_THREAD_SUPPORT)
237 return(pthread_setspecific(key,value) == 0 ? MagickTrue : MagickFalse);
238 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
239 return(TlsSetValue(key,(void *) value) != 0 ? MagickTrue : MagickFalse);
245 keys=(MagickThreadValue *) key;
246 keys->values[GetOpenMPThreadId()]=(void *) value;