2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % SSSSS EEEEE M M AAA PPPP H H OOO RRRR EEEEE %
7 % SS E MM MM A A P P H H O O R R E %
8 % SSS EEE M M M AAAAA PPPP HHHHH O O RRRR EEE %
9 % SS E M M A A P H H O O R R E %
10 % SSSSS EEEEE M M A A P H H OOO R R EEEEE %
13 % MagickCore Semaphore Methods %
21 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % http://www.imagemagick.org/script/license.php %
29 % Unless required by applicable law or agreed to in writing, software %
30 % distributed under the License is distributed on an "AS IS" BASIS, %
31 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32 % See the License for the specific language governing permissions and %
33 % limitations under the License. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44 #include "magick/studio.h"
45 #include "magick/exception.h"
46 #include "magick/exception-private.h"
47 #include "magick/memory_.h"
48 #include "magick/semaphore.h"
49 #include "magick/semaphore-private.h"
50 #include "magick/string_.h"
51 #include "magick/thread_.h"
52 #include "magick/thread-private.h"
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 % A c q u i r e S e m a p h o r e I n f o %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % AcquireSemaphoreInfo() acquires a semaphore.
85 % The format of the AcquireSemaphoreInfo method is:
87 % void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
89 % A description of each parameter follows:
91 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
94 MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
96 assert(semaphore_info != (SemaphoreInfo **) NULL);
97 if (*semaphore_info == (SemaphoreInfo *) NULL)
100 if (*semaphore_info == (SemaphoreInfo *) NULL)
101 *semaphore_info=AllocateSemaphoreInfo();
107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111 % A l l o c a t e S e m a p h o r e I n f o %
115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117 % AllocateSemaphoreInfo() initializes the SemaphoreInfo structure.
119 % The format of the AllocateSemaphoreInfo method is:
121 % SemaphoreInfo *AllocateSemaphoreInfo(void)
124 MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
132 semaphore_info=(SemaphoreInfo *) malloc(sizeof(SemaphoreInfo));
133 if (semaphore_info == (SemaphoreInfo *) NULL)
134 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
135 (void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo));
137 Initialize the semaphore.
139 #if defined(MAGICKCORE_THREAD_SUPPORT)
147 status=pthread_mutexattr_init(&mutex_info);
151 ThrowFatalException(ResourceLimitFatalError,
152 "UnableToInitializeSemaphore");
154 status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
158 ThrowFatalException(ResourceLimitFatalError,
159 "UnableToInitializeSemaphore");
161 status=pthread_mutexattr_destroy(&mutex_info);
165 ThrowFatalException(ResourceLimitFatalError,
166 "UnableToInitializeSemaphore");
169 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
174 status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400);
178 ThrowFatalException(ResourceLimitFatalError,
179 "UnableToInitializeSemaphore");
183 semaphore_info->id=GetMagickThreadId();
184 semaphore_info->reference_count=0;
185 semaphore_info->signature=MagickSignature;
186 return(semaphore_info);
190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 % D e s t r o y S e m a p h o r e I n f o %
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200 % DestroySemaphoreInfo() destroys a semaphore.
202 % The format of the DestroySemaphoreInfo method is:
204 % void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
206 % A description of each parameter follows:
208 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
211 MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
213 assert(semaphore_info != (SemaphoreInfo **) NULL);
214 assert((*semaphore_info) != (SemaphoreInfo *) NULL);
215 assert((*semaphore_info)->signature == MagickSignature);
217 #if defined(MAGICKCORE_THREAD_SUPPORT)
222 status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
226 ThrowFatalException(ResourceLimitFatalError,"UnableToDestroySemaphore");
229 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
230 DeleteCriticalSection(&(*semaphore_info)->mutex);
232 (*semaphore_info)->signature=(~MagickSignature);
233 free(*semaphore_info);
234 *semaphore_info=(SemaphoreInfo *) NULL;
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243 % L o c k S e m a p h o r e I n f o %
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % LockSemaphoreInfo() locks a semaphore.
251 % The format of the LockSemaphoreInfo method is:
253 % void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
255 % A description of each parameter follows:
257 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
260 MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
262 assert(semaphore_info != (SemaphoreInfo *) NULL);
263 assert(semaphore_info->signature == MagickSignature);
264 #if defined(MAGICKCORE_THREAD_SUPPORT)
269 status=pthread_mutex_lock(&semaphore_info->mutex);
273 ThrowFatalException(ResourceLimitFatalError,"UnableToLockSemaphore");
276 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
277 EnterCriticalSection(&semaphore_info->mutex);
279 #if defined(MAGICKCORE_DEBUG)
280 if ((semaphore_info->reference_count > 0) &&
281 (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
283 (void) fprintf(stderr,"Warning: unexpected recursive lock!\n");
284 (void) fflush(stderr);
287 semaphore_info->id=GetMagickThreadId();
288 semaphore_info->reference_count++;
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296 % R e l i n g u i s h S e m a p h o r e I n f o %
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 % RelinquishSemaphoreInfo() relinquishes a semaphore.
304 % The format of the RelinquishSemaphoreInfo method is:
306 % RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
308 % A description of each parameter follows:
310 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
313 MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
315 assert(semaphore_info != (SemaphoreInfo *) NULL);
316 assert(semaphore_info->signature == MagickSignature);
317 UnlockSemaphoreInfo(semaphore_info);
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325 % S e m a p h o r e C o m p o n e n t G e n e s i s %
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331 % SemaphoreComponentGenesis() instantiates the semaphore environment.
333 % The format of the SemaphoreComponentGenesis method is:
335 % MagickBooleanType SemaphoreComponentGenesis(void)
338 MagickExport MagickBooleanType SemaphoreComponentGenesis(void)
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 % S e m a p h o r e C o m p o n e n t T e r m i n u s %
354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 % SemaphoreComponentTerminus() destroys the semaphore component.
358 % The format of the SemaphoreComponentTerminus method is:
360 % SemaphoreComponentTerminus(void)
363 MagickExport void SemaphoreComponentTerminus(void)
368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 % U n l o c k S e m a p h o r e I n f o %
376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 % UnlockSemaphoreInfo() unlocks a semaphore.
380 % The format of the UnlockSemaphoreInfo method is:
382 % void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
384 % A description of each parameter follows:
386 % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
389 MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
391 assert(semaphore_info != (SemaphoreInfo *) NULL);
392 assert(semaphore_info->signature == MagickSignature);
393 #if defined(MAGICKCORE_DEBUG)
394 assert(IsMagickThreadEqual(semaphore_info->id) != MagickFalse);
395 if (semaphore_info->reference_count == 0)
397 (void) fprintf(stderr,"Warning: semaphore lock already unlocked!\n");
398 (void) fflush(stderr);
401 semaphore_info->reference_count--;
403 #if defined(MAGICKCORE_THREAD_SUPPORT)
408 status=pthread_mutex_unlock(&semaphore_info->mutex);
412 ThrowFatalException(ResourceLimitFatalError,"UnableToUnlockSemaphore");
415 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
416 LeaveCriticalSection(&semaphore_info->mutex);