Coverage Report

Created: 2025-08-11 08:01

/src/graphicsmagick/magick/semaphore.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
% Copyright (C) 2003-2012 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
%
5
% This program is covered by multiple licenses, which are described in
6
% Copyright.txt. You should have received a copy of Copyright.txt with this
7
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
8
%
9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
%                                                                             %
11
%                                                                             %
12
%        SSSSS  EEEEE  M   M   AAA   PPPP   H   H   OOO   RRRR   EEEEE        %
13
%        SS     E      MM MM  A   A  P   P  H   H  O   O  R   R  E            %
14
%         SSS   EEE    M M M  AAAAA  PPPP   HHHHH  O   O  RRRR   EEE          %
15
%           SS  E      M   M  A   A  P      H   H  O   O  R R    E            %
16
%        SSSSS  EEEEE  M   M  A   A  P      H   H   OOO   R  R   EEEEE        %
17
%                                                                             %
18
%                                                                             %
19
%                     GraphicsMagick Semaphore Methods                        %
20
%                                                                             %
21
%                                                                             %
22
%                              Software Design                                %
23
%                             William Radcliffe                               %
24
%                                John Cristy                                  %
25
%                                 June 2000                                   %
26
%                                                                             %
27
%                                                                             %
28
%                                                                             %
29
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30
%
31
%
32
%
33
*/
34

35
/*
36
  Include declarations.
37
*/
38
#include "magick/studio.h"
39
#include "magick/utility.h"
40
41
#if defined(HAVE_PTHREAD)
42
#  define USE_PTHREAD_LOCKS 1
43
#elif defined(MSWINDOWS)
44
#  define USE_WIN32_LOCKS 1
45
#elif defined(HAVE_OPENMP)
46
#  define USE_OPENMP_LOCKS 1
47
#endif
48
49
#if defined(USE_PTHREAD_LOCKS)
50
#  include <pthread.h>
51
#  define PTHREAD_MUTEX_DESTROY(semaphore_mutex)                        \
52
11.9M
  {                                                                     \
53
11.9M
    int                                                                 \
54
11.9M
      err_status;                                                       \
55
11.9M
                                                                        \
56
11.9M
    if ((err_status = pthread_mutex_destroy(semaphore_mutex)) != 0)     \
57
11.9M
      {                                                                 \
58
0
        errno=err_status;                                               \
59
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
60
0
                          UnableToDestroySemaphore);                    \
61
0
      }                                                                 \
62
11.9M
  }
63
#  define PTHREAD_MUTEXATTR_DESTROY(mutexattr)                          \
64
11.9M
  {                                                                     \
65
11.9M
    int                                                                 \
66
11.9M
      err_status;                                                       \
67
11.9M
                                                                        \
68
11.9M
    if ((err_status = pthread_mutexattr_destroy(mutexattr)) != 0)       \
69
11.9M
      {                                                                 \
70
0
        errno=err_status;                                               \
71
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
72
0
                          UnableToDestroySemaphore);                    \
73
0
      }                                                                 \
74
11.9M
  }
75
#  define PTHREAD_MUTEXATTR_INIT(mutexattr)                             \
76
11.9M
  {                                                                     \
77
11.9M
    int                                                                 \
78
11.9M
      err_status;                                                       \
79
11.9M
                                                                        \
80
11.9M
    if ((err_status = pthread_mutexattr_init(mutexattr)) != 0)          \
81
11.9M
      {                                                                 \
82
0
        errno=err_status;                                               \
83
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
84
0
                          UnableToInitializeSemaphore);                 \
85
0
      }                                                                 \
86
11.9M
  }
87
#  define PTHREAD_MUTEXATTR_SETTYPE(mutexattr,mutexattrtype)            \
88
  {                                                                     \
89
    int                                                                 \
90
      err_status;                                                       \
91
                                                                        \
92
    if ((err_status = pthread_mutexattr_settype(mutexattr,mutexattrtype)) != 0) \
93
      {                                                                 \
94
        errno=err_status;                                               \
95
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
96
                          UnableToInitializeSemaphore);                 \
97
      }                                                                 \
98
  }
99
#  define PTHREAD_MUTEX_INIT(semaphore_mutex,mutexattr)                 \
100
11.9M
  {                                                                     \
101
11.9M
    int                                                                 \
102
11.9M
      err_status;                                                       \
103
11.9M
                                                                        \
104
11.9M
    if ((err_status = pthread_mutex_init(semaphore_mutex,mutexattr)) != 0) \
105
11.9M
      {                                                                 \
106
0
        errno=err_status;                                               \
107
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
108
0
                          UnableToInitializeSemaphore);                 \
109
0
      }                                                                 \
110
11.9M
  }
111
#  define PTHREAD_MUTEX_LOCK(semaphore_mutex)                           \
112
717M
  {                                                                     \
113
717M
    int                                                                 \
114
717M
      err_status;                                                       \
115
717M
                                                                        \
116
717M
    if ((err_status = pthread_mutex_lock(semaphore_mutex)) != 0)        \
117
717M
      {                                                                 \
118
0
        errno=err_status;                                               \
119
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
120
0
                          UnableToLockSemaphore);                       \
121
0
      }                                                                 \
122
717M
  }
123
#  define PTHREAD_MUTEX_UNLOCK(semaphore_mutex)                         \
124
717M
  {                                                                     \
125
717M
    int                                                                 \
126
717M
      err_status;                                                       \
127
717M
                                                                        \
128
717M
    if ((err_status = pthread_mutex_unlock(semaphore_mutex)) != 0)      \
129
717M
      {                                                                 \
130
0
        errno=err_status;                                               \
131
0
        MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
132
0
                          UnableToUnlockSemaphore);                     \
133
0
      }                                                                 \
134
717M
  }
135
#endif
136
137
#if defined(USE_WIN32_LOCKS)
138
#  include <windows.h>
139
#  define USE_SPINLOCKS
140
#  define SPINLOCK_DELAY_MILLI_SECS 10
141
#endif
142
143
#include "magick/semaphore.h"
144

145
/*
146
  Struct declaractions.
147
*/
148
struct _SemaphoreInfo
149
{
150
#if defined(USE_OPENMP_LOCKS)
151
  omp_lock_t
152
    mutex;              /* OpenMP lock */
153
#endif /* defined(USE_OPENMP_LOCKS) */
154
#if defined(USE_PTHREAD_LOCKS)
155
  pthread_mutex_t
156
    mutex;              /* POSIX thread mutex */
157
#endif /* if defined(USE_PTHREAD_LOCKS) */
158
#if defined(USE_WIN32_LOCKS)
159
  CRITICAL_SECTION
160
    mutex;              /* Windows critical section */
161
#endif /* defined(USE_WIN32_LOCKS) */
162
163
  unsigned long
164
    signature;          /* Used to validate structure */
165
};
166

167
/*
168
  Static declaractions.
169
*/
170
#if defined(USE_OPENMP_LOCKS)
171
static omp_lock_t
172
  semaphore_mutex;
173
174
static unsigned int
175
  active_semaphore = MagickFalse;
176
#endif /* defined(USE_OPENMP_LOCKS) */
177
178
#if defined(USE_PTHREAD_LOCKS)
179
static pthread_mutex_t
180
  semaphore_mutex = PTHREAD_MUTEX_INITIALIZER;
181
#endif /* defined(USE_PTHREAD_LOCKS) */
182
183
#if defined(USE_WIN32_LOCKS)
184
#if !defined(USE_SPINLOCKS)
185
static CRITICAL_SECTION
186
  semaphore_mutex;
187
188
static unsigned int
189
  active_semaphore = MagickFalse;
190
#else
191
static LONG
192
  semaphore_mutex = 0;
193
/* Wait for spin lock */
194
static void spinlock_wait (LONG volatile *sl)
195
{
196
  /*
197
    InterlockedCompareExchange performs an atomic comparison of the
198
    specified 32-bit values and exchanges them, based on the outcome of
199
    the comparison. Requires Windows XP, Windows 2000 Professional,
200
    Windows NT Workstation 4.0, Windows Me, or Windows 98.
201
   */
202
203
  while (InterlockedCompareExchange (sl, 1L, 0L) != 0)
204
  {
205
    /* slight delay - just in case OS does not giveup CPU */
206
    Sleep (SPINLOCK_DELAY_MILLI_SECS);
207
  }
208
}
209
/* Release spin lock */
210
static void spinlock_release (LONG volatile *sl)
211
{
212
  /*
213
    InterlockedExchange atomically exchanges a pair of 32-bit
214
    values. Requires Windows XP, Windows 2000 Professional, Windows NT
215
    Workstation 3.5 and later, Windows Me, Windows 98, or Windows 95.
216
  */
217
  InterlockedExchange (sl, 0L);
218
}
219
#endif
220
#endif
221

222
/*
223
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224
%                                                                             %
225
%                                                                             %
226
%                                                                             %
227
%   A c q u i r e S e m a p h o r e I n f o                                   %
228
%                                                                             %
229
%                                                                             %
230
%                                                                             %
231
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232
%
233
%  AcquireSemaphoreInfo() locks a semaphore, initializing it first if
234
%  necessary.
235
%
236
%  This function is deprecated, should not be used for new code, and should
237
%  be removed when possible from existing code.
238
%
239
%  The format of the AcquireSemaphoreInfo method is:
240
%
241
%      void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
242
%
243
%  A description of each parameter follows:
244
%
245
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
246
%
247
%
248
*/
249
MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
250
0
{
251
0
  assert(semaphore_info != (SemaphoreInfo **) NULL);
252
#if defined(USE_OPENMP_LOCKS)
253
  if (!active_semaphore)
254
    {
255
      omp_init_lock(&semaphore_mutex);
256
      active_semaphore=MagickTrue;
257
    }
258
  omp_set_lock(&semaphore_mutex);
259
#endif /* defined(USE_OPENMP_LOCKS) */
260
0
#if defined(USE_PTHREAD_LOCKS)
261
0
  PTHREAD_MUTEX_LOCK(&semaphore_mutex);
262
0
#endif /* defined(USE_PTHREAD_LOCKS) */
263
#if defined(USE_WIN32_LOCKS)
264
#  if !defined(USE_SPINLOCKS)
265
  if (!active_semaphore)
266
    {
267
      InitializeCriticalSection(&semaphore_mutex);
268
      active_semaphore=MagickTrue;
269
    }
270
  EnterCriticalSection(&semaphore_mutex);
271
#  else
272
  spinlock_wait(&semaphore_mutex);
273
#  endif
274
#endif /* defined(USE_WIN32_LOCKS) */
275
0
  if (*semaphore_info == (SemaphoreInfo *) NULL)
276
0
    *semaphore_info=AllocateSemaphoreInfo();
277
#if defined(USE_OPENMP_LOCKS)
278
  omp_unset_lock(&semaphore_mutex);
279
#endif /* defined(USE_OPENMP_LOCKS) */
280
0
#if defined(USE_PTHREAD_LOCKS)
281
0
  PTHREAD_MUTEX_UNLOCK(&semaphore_mutex);
282
0
#endif /* defined(USE_PTHREAD_LOCKS) */
283
#if defined(USE_WIN32_LOCKS)
284
#if !defined(USE_SPINLOCKS)
285
  LeaveCriticalSection(&semaphore_mutex);
286
#else
287
  spinlock_release(&semaphore_mutex);
288
#endif
289
#endif
290
0
  (void) LockSemaphoreInfo(*semaphore_info);
291
0
}
292

293
/*
294
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295
%                                                                             %
296
%                                                                             %
297
%                                                                             %
298
%   A l l o c a t e S e m a p h o r e I n f o                                 %
299
%                                                                             %
300
%                                                                             %
301
%                                                                             %
302
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303
%
304
%  Method AllocateSemaphoreInfo initializes the SemaphoreInfo structure.
305
%
306
%  The format of the AllocateSemaphoreInfo method is:
307
%
308
%      SemaphoreInfo *AllocateSemaphoreInfo(void)
309
%
310
%  A description of each parameter follows:
311
%
312
%    o semaphore_info: Method AllocateSemaphoreInfo returns a pointer to an
313
%      initialized SemaphoreInfo structure.
314
%
315
%
316
*/
317
MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
318
11.9M
{
319
11.9M
  SemaphoreInfo
320
11.9M
    *semaphore_info;
321
322
  /*
323
    Allocate semaphore.
324
  */
325
11.9M
  semaphore_info=MagickAllocateAlignedMemory(SemaphoreInfo *,
326
11.9M
                                             MAGICK_CACHE_LINE_SIZE,
327
11.9M
                                             sizeof(SemaphoreInfo));
328
11.9M
  if (semaphore_info == (SemaphoreInfo *) NULL)
329
0
    MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
330
11.9M
      UnableToAllocateSemaphoreInfo);
331
11.9M
  (void) memset(semaphore_info,0,sizeof(SemaphoreInfo));
332
  /*
333
    Initialize the semaphore.
334
  */
335
#if defined(USE_OPENMP_LOCKS)
336
  omp_init_lock(&semaphore_info->mutex);
337
#endif /* defined(USE_OPENMP_LOCKS) */
338
11.9M
#if defined(USE_PTHREAD_LOCKS)
339
11.9M
  {
340
11.9M
    pthread_mutexattr_t
341
11.9M
      mutexattr;
342
343
11.9M
    PTHREAD_MUTEXATTR_INIT(&mutexattr);
344
345
    /*
346
      If MAGICK_DEBUG is defined then enable pthread mutex error
347
      checks.
348
    */
349
#if MAGICK_DEBUG
350
#if defined(PTHREAD_MUTEX_ERRORCHECK)
351
    PTHREAD_MUTEXATTR_SETTYPE(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
352
#endif /* PTHREAD_MUTEX_ERRORCHECK */
353
#endif /* MAGICK_DEBUG */
354
355
11.9M
    PTHREAD_MUTEX_INIT(&semaphore_info->mutex,&mutexattr);
356
11.9M
    PTHREAD_MUTEXATTR_DESTROY(&mutexattr);
357
11.9M
  }
358
0
#endif
359
#if defined(USE_WIN32_LOCKS)
360
  InitializeCriticalSection(&semaphore_info->mutex);
361
#endif
362
363
11.9M
  semaphore_info->signature=MagickSignature;
364
11.9M
  return(semaphore_info);
365
11.9M
}
366

367
/*
368
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369
%                                                                             %
370
%                                                                             %
371
%                                                                             %
372
%   D e s t r o y S e m a p h o r e                                           %
373
%                                                                             %
374
%                                                                             %
375
%                                                                             %
376
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377
%
378
%  DestroySemaphore() destroys the semaphore environment.
379
%
380
%  The format of the DestroySemaphore method is:
381
%
382
%      void DestroySemaphore(void)
383
%
384
%
385
*/
386
MagickExport void DestroySemaphore(void)
387
0
{
388
#if defined(USE_OPENMP_LOCKS)
389
  if (active_semaphore)
390
    {
391
      omp_destroy_lock(&semaphore_mutex);
392
      active_semaphore=MagickFalse;
393
    }
394
#endif /* defined(USE_OPENMP_LOCKS) */
395
0
#if defined(USE_PTHREAD_LOCKS)
396
  /*
397
    We use static pthread mutex initialization with
398
    PTHREAD_MUTEX_INITIALIZER so semaphore mutex should not be
399
    destroyed.
400
  */
401
  /* PTHREAD_MUTEX_DESTROY(&semaphore_mutex); */
402
0
#endif
403
#if defined(USE_WIN32_LOCKS)
404
#if !defined(USE_SPINLOCKS)
405
  if (active_semaphore)
406
    {
407
      DeleteCriticalSection(&semaphore_mutex);
408
      active_semaphore=MagickFalse;
409
    }
410
#endif
411
#endif
412
0
}
413

414
/*
415
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416
%                                                                             %
417
%                                                                             %
418
%                                                                             %
419
%   D e s t r o y S e m a p h o r e I n f o                                   %
420
%                                                                             %
421
%                                                                             %
422
%                                                                             %
423
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424
%
425
%  Method DestroySemaphoreInfo destroys a semaphore.
426
%
427
%  The format of the DestroySemaphoreInfo method is:
428
%
429
%      void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
430
%
431
%  A description of each parameter follows:
432
%
433
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
434
%
435
%
436
*/
437
MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
438
11.9M
{
439
11.9M
  assert(semaphore_info != (SemaphoreInfo **) NULL);
440
11.9M
  if (*semaphore_info == (SemaphoreInfo *) NULL)
441
0
    return;
442
11.9M
  assert((*semaphore_info)->signature == MagickSignature);
443
#if defined(USE_OPENMP_LOCKS)
444
  if (!active_semaphore)
445
    {
446
      omp_init_lock(&semaphore_mutex);
447
      active_semaphore=MagickTrue;
448
    }
449
  omp_set_lock(&semaphore_mutex);
450
#endif /* defined(USE_OPENMP_LOCKS) */
451
11.9M
#if defined(USE_PTHREAD_LOCKS)
452
11.9M
  PTHREAD_MUTEX_LOCK(&semaphore_mutex);
453
11.9M
#endif
454
#if defined(USE_WIN32_LOCKS)
455
#if !defined(USE_SPINLOCKS)
456
  if (!active_semaphore)
457
    {
458
      InitializeCriticalSection(&semaphore_mutex);
459
      active_semaphore=MagickTrue;
460
    }
461
  EnterCriticalSection(&semaphore_mutex);
462
#else
463
  spinlock_wait(&semaphore_mutex);
464
#endif
465
#endif
466
#if defined(USE_OPENMP_LOCKS)
467
  omp_destroy_lock(&(*semaphore_info)->mutex);
468
#endif /* defined(USE_OPENMP_LOCKS) */
469
11.9M
#if defined(USE_PTHREAD_LOCKS)
470
11.9M
  PTHREAD_MUTEX_DESTROY(&(*semaphore_info)->mutex);
471
11.9M
#endif
472
#if defined(USE_WIN32_LOCKS)
473
  DeleteCriticalSection(&(*semaphore_info)->mutex);
474
#endif
475
11.9M
  (void) memset((void *) *semaphore_info,0xbf,sizeof(SemaphoreInfo));
476
11.9M
  MagickFreeAlignedMemory((*semaphore_info));
477
#if defined(USE_OPENMP_LOCKS)
478
  omp_unset_lock(&semaphore_mutex);
479
#endif /* defined(USE_OPENMP_LOCKS) */
480
11.9M
#if defined(USE_PTHREAD_LOCKS)
481
11.9M
  PTHREAD_MUTEX_UNLOCK(&semaphore_mutex);
482
11.9M
#endif
483
#if defined(USE_WIN32_LOCKS)
484
#if !defined(USE_SPINLOCKS)
485
  LeaveCriticalSection(&semaphore_mutex);
486
#else
487
  spinlock_release(&semaphore_mutex);
488
#endif
489
#endif
490
11.9M
}
491

492
/*
493
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494
%                                                                             %
495
%                                                                             %
496
%                                                                             %
497
%   I n i t i a l i z e S e m a p h o r e                                     %
498
%                                                                             %
499
%                                                                             %
500
%                                                                             %
501
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502
%
503
%  Method InitializeSemaphore initializes the semaphore environment.
504
%
505
%  The format of the InitializeSemaphore method is:
506
%
507
%      void InitializeSemaphore(void)
508
%
509
%
510
*/
511
MagickExport void InitializeSemaphore(void)
512
250
{
513
#if defined(USE_OPENMP_LOCKS)
514
  if (!active_semaphore)
515
    {
516
      omp_init_lock(&semaphore_mutex);
517
      active_semaphore=MagickTrue;
518
    }
519
#endif /* defined(USE_OPENMP_LOCKS) */
520
250
#if defined(USE_PTHREAD_LOCKS)
521
  /*
522
    We use static pthread mutex initialization with
523
    PTHREAD_MUTEX_INITIALIZER so explicit runtime initialization is
524
    not required.
525
  */
526
/*   (void) pthread_mutex_init(&semaphore_mutex, */
527
/*     (const pthread_mutexattr_t *) NULL); */
528
250
#endif
529
#if defined(USE_WIN32_LOCKS)
530
#if !defined(USE_SPINLOCKS)
531
  if (!active_semaphore)
532
    {
533
      InitializeCriticalSection(&semaphore_mutex);
534
      active_semaphore=MagickTrue;
535
    }
536
#endif
537
#endif
538
250
}
539

540
/*
541
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
542
%                                                                             %
543
%                                                                             %
544
%                                                                             %
545
%   L i b e r a t e S e m a p h o r e I n f o                                 %
546
%                                                                             %
547
%                                                                             %
548
%                                                                             %
549
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
550
%
551
%  Method LiberateSemaphoreInfo unlocks the semaphore if it has been allocated.
552
%
553
%  This function is deprecated, should not be used for new code, and should
554
%  be removed when possible from existing code.
555
%
556
%  The format of the LiberateSemaphoreInfo method is:
557
%
558
%      void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
559
%
560
%  A description of each parameter follows:
561
%
562
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
563
%
564
%
565
*/
566
MagickExport void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
567
0
{
568
0
  assert(semaphore_info != (SemaphoreInfo **) NULL);
569
0
  if (*semaphore_info != (SemaphoreInfo *) NULL)
570
0
    {
571
0
      assert((*semaphore_info)->signature == MagickSignature);
572
0
      (void) UnlockSemaphoreInfo(*semaphore_info);
573
0
    }
574
0
}
575

576
/*
577
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578
%                                                                             %
579
%                                                                             %
580
%                                                                             %
581
%   L o c k S e m a p h o r e I n f o                                         %
582
%                                                                             %
583
%                                                                             %
584
%                                                                             %
585
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
586
%
587
%  Method LockSemaphoreInfo locks a semaphore.
588
%
589
%  The format of the LockSemaphoreInfo method is:
590
%
591
%      void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
592
%
593
%  A description of each parameter follows:
594
%
595
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
596
%
597
%
598
*/
599
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
600
705M
{
601
705M
  assert(semaphore_info != (SemaphoreInfo *) NULL);
602
705M
  assert(semaphore_info->signature == MagickSignature);
603
#if defined(USE_OPENMP_LOCKS)
604
  omp_set_lock(&semaphore_info->mutex);
605
#endif /* defined(USE_OPENMP_LOCKS) */
606
705M
#if defined(USE_PTHREAD_LOCKS)
607
705M
  PTHREAD_MUTEX_LOCK(&semaphore_info->mutex);
608
705M
#endif /* defined(USE_PTHREAD_LOCKS) */
609
#if defined(USE_WIN32_LOCKS)
610
  EnterCriticalSection(&semaphore_info->mutex);
611
#endif /* defined(USE_WIN32_LOCKS) */
612
705M
}
613

614
/*
615
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616
%                                                                             %
617
%                                                                             %
618
%                                                                             %
619
%   U n l o c k S e m a p h o r e I n f o                                     %
620
%                                                                             %
621
%                                                                             %
622
%                                                                             %
623
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624
%
625
%  Method UnlockSemaphoreInfo unlocks a semaphore.
626
%
627
%  The format of the LockSemaphoreInfo method is:
628
%
629
%      void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
630
%
631
%  A description of each parameter follows:
632
%
633
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
634
%
635
%
636
*/
637
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
638
705M
{
639
705M
  assert(semaphore_info != (SemaphoreInfo *) NULL);
640
705M
  assert(semaphore_info->signature == MagickSignature);
641
642
#if defined(USE_OPENMP_LOCKS)
643
  omp_unset_lock(&semaphore_info->mutex);
644
#endif /* defined(USE_OPENMP_LOCKS) */
645
705M
#if defined(USE_PTHREAD_LOCKS)
646
705M
  PTHREAD_MUTEX_UNLOCK(&semaphore_info->mutex);
647
705M
#endif /* defined(USE_PTHREAD_LOCKS) */
648
#if defined(USE_WIN32_LOCKS)
649
  LeaveCriticalSection(&semaphore_info->mutex);
650
#endif /* defined(USE_WIN32_LOCKS) */
651
705M
}