~ubuntu-branches/ubuntu/intrepid/graphicsmagick/intrepid

« back to all changes in this revision

Viewing changes to magick/semaphore.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2006-05-06 16:28:08 UTC
  • Revision ID: james.westby@ubuntu.com-20060506162808-vt2ni3r5nytcszms
Tags: upstream-1.1.7
ImportĀ upstreamĀ versionĀ 1.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
% Copyright (C) 2003 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
#if defined(HAVE_PTHREAD)
 
41
#include <pthread.h>
 
42
#endif
 
43
#if defined(WIN32)
 
44
#include <windows.h>
 
45
#define USE_SPINLOCKS
 
46
#define SPINLOCK_DELAY_MILLI_SECS 10
 
47
#endif
 
48
#include "magick/semaphore.h"
 
49
 
 
50
/*
 
51
  Struct declaractions.
 
52
*/
 
53
struct SemaphoreInfo
 
54
{
 
55
#if defined(HAVE_PTHREAD)
 
56
  pthread_mutex_t
 
57
    mutex;              /* POSIX thread mutex */
 
58
 
 
59
  pthread_t
 
60
    thread_id;          /* ID of thread which holds the lock */
 
61
#endif
 
62
#if defined(WIN32)
 
63
  CRITICAL_SECTION
 
64
    mutex;              /* Windows critical section */
 
65
 
 
66
  DWORD
 
67
    thread_id;          /* ID of thread which holds the lock */
 
68
#endif
 
69
 
 
70
  unsigned int
 
71
    locked;             /* True if semaphore is locked */
 
72
 
 
73
  unsigned long
 
74
    signature;          /* Used to validate structure */
 
75
};
 
76
 
 
77
/*
 
78
  Static declaractions.
 
79
*/
 
80
#if defined(HAVE_PTHREAD)
 
81
static pthread_mutex_t
 
82
  semaphore_mutex = PTHREAD_MUTEX_INITIALIZER;
 
83
#endif
 
84
 
 
85
#if defined(WIN32)
 
86
#if !defined(USE_SPINLOCKS)
 
87
static CRITICAL_SECTION
 
88
  semaphore_mutex;
 
89
 
 
90
static unsigned int
 
91
  active_semaphore = False;
 
92
#else
 
93
static int
 
94
  semaphore_mutex = 0;
 
95
/* Wait for spin lock */
 
96
static void spinlock_wait (int *sl)
 
97
{
 
98
  while (InterlockedCompareExchange (sl, 1, 0) != 0)
 
99
  {
 
100
    /* slight delay - just in case OS does not giveup CPU */
 
101
    Sleep (SPINLOCK_DELAY_MILLI_SECS);
 
102
  }
 
103
}
 
104
/* Release spin lock */
 
105
static void spinlock_release (int *sl)
 
106
{
 
107
  InterlockedExchange (sl, 0);
 
108
}
 
109
#endif
 
110
#endif
 
111
 
 
112
/*
 
113
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
114
%                                                                             %
 
115
%                                                                             %
 
116
%                                                                             %
 
117
%   A c q u i r e S e m a p h o r e I n f o                                   %
 
118
%                                                                             %
 
119
%                                                                             %
 
120
%                                                                             %
 
121
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
122
%
 
123
%  AcquireSemaphoreInfo() acquires a semaphore.
 
124
%
 
125
%  The format of the AcquireSemaphoreInfo method is:
 
126
%
 
127
%      AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
 
128
%
 
129
%  A description of each parameter follows:
 
130
%
 
131
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
 
132
%
 
133
%
 
134
*/
 
135
MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
 
136
{
 
137
  assert(semaphore_info != (SemaphoreInfo **) NULL);
 
138
#if defined(HAVE_PTHREAD)
 
139
  (void) pthread_mutex_lock(&semaphore_mutex);
 
140
#endif
 
141
#if defined(WIN32)
 
142
#if !defined(USE_SPINLOCKS)
 
143
  if (!active_semaphore)
 
144
    InitializeCriticalSection(&semaphore_mutex);
 
145
  active_semaphore=True;
 
146
  EnterCriticalSection(&semaphore_mutex);
 
147
#else
 
148
  spinlock_wait(&semaphore_mutex);
 
149
#endif
 
150
#endif
 
151
  if (*semaphore_info == (SemaphoreInfo *) NULL)
 
152
    *semaphore_info=AllocateSemaphoreInfo();
 
153
#if defined(HAVE_PTHREAD)
 
154
  (void) pthread_mutex_unlock(&semaphore_mutex);
 
155
#endif
 
156
#if defined(WIN32)
 
157
#if !defined(USE_SPINLOCKS)
 
158
  LeaveCriticalSection(&semaphore_mutex);
 
159
#else
 
160
  spinlock_release(&semaphore_mutex);
 
161
#endif
 
162
#endif
 
163
  (void) LockSemaphoreInfo(*semaphore_info);
 
164
}
 
165
 
 
166
/*
 
167
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
168
%                                                                             %
 
169
%                                                                             %
 
170
%                                                                             %
 
171
%   A l l o c a t e S e m a p h o r e I n f o                                 %
 
172
%                                                                             %
 
173
%                                                                             %
 
174
%                                                                             %
 
175
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
176
%
 
177
%  Method AllocateSemaphoreInfo initializes the SemaphoreInfo structure.
 
178
%
 
179
%  The format of the AllocateSemaphoreInfo method is:
 
180
%
 
181
%      SemaphoreInfo *AllocateSemaphoreInfo(void)
 
182
%
 
183
%  A description of each parameter follows:
 
184
%
 
185
%    o semaphore_info: Method AllocateSemaphoreInfo returns a pointer to an
 
186
%      initialized SemaphoreInfo structure.
 
187
%
 
188
%
 
189
*/
 
190
MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
 
191
{
 
192
  SemaphoreInfo
 
193
    *semaphore_info;
 
194
 
 
195
  /*
 
196
    Allocate semaphore.
 
197
  */
 
198
  semaphore_info=MagickAllocateMemory(SemaphoreInfo *,sizeof(SemaphoreInfo));
 
199
  if (semaphore_info == (SemaphoreInfo *) NULL)
 
200
    MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
 
201
      UnableToAllocateSemaphoreInfo);
 
202
  memset(semaphore_info,0,sizeof(SemaphoreInfo));
 
203
  /*
 
204
    Initialize the semaphore.
 
205
  */
 
206
#if defined(HAVE_PTHREAD)
 
207
  {
 
208
    int
 
209
      status;
 
210
 
 
211
    status=pthread_mutex_init(&semaphore_info->mutex,
 
212
      (const pthread_mutexattr_t *) NULL);
 
213
    if (status != 0)
 
214
      {
 
215
        MagickFreeMemory(semaphore_info);
 
216
        return((SemaphoreInfo *) NULL);
 
217
      }
 
218
  }
 
219
#endif
 
220
#if defined(WIN32)
 
221
  InitializeCriticalSection(&semaphore_info->mutex);
 
222
#endif
 
223
  semaphore_info->locked=False;
 
224
  semaphore_info->signature=MagickSignature;
 
225
  return(semaphore_info);
 
226
}
 
227
 
 
228
/*
 
229
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
230
%                                                                             %
 
231
%                                                                             %
 
232
%                                                                             %
 
233
%   D e s t r o y S e m a p h o r e                                           %
 
234
%                                                                             %
 
235
%                                                                             %
 
236
%                                                                             %
 
237
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
238
%
 
239
%  DestroySemaphore() destroys the semaphore environment.
 
240
%
 
241
%  The format of the DestroySemaphore method is:
 
242
%
 
243
%      DestroySemaphore(void)
 
244
%
 
245
%
 
246
*/
 
247
MagickExport void DestroySemaphore(void)
 
248
{
 
249
#if defined(HAVE_PTHREAD)
 
250
  (void) pthread_mutex_destroy(&semaphore_mutex);
 
251
#endif
 
252
#if defined(WIN32)
 
253
#if !defined(USE_SPINLOCKS)
 
254
  if (active_semaphore)
 
255
    DeleteCriticalSection(&semaphore_mutex);
 
256
  active_semaphore=False;
 
257
#endif
 
258
#endif
 
259
}
 
260
 
 
261
/*
 
262
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
263
%                                                                             %
 
264
%                                                                             %
 
265
%                                                                             %
 
266
%   D e s t r o y S e m a p h o r e I n f o                                   %
 
267
%                                                                             %
 
268
%                                                                             %
 
269
%                                                                             %
 
270
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
271
%
 
272
%  Method DestroySemaphoreInfo destroys a semaphore.
 
273
%
 
274
%  The format of the DestroySemaphoreInfo method is:
 
275
%
 
276
%      DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
 
277
%
 
278
%  A description of each parameter follows:
 
279
%
 
280
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
 
281
%
 
282
%
 
283
*/
 
284
MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
 
285
{
 
286
  assert(semaphore_info != (SemaphoreInfo **) NULL);
 
287
  if (*semaphore_info == (SemaphoreInfo *) NULL)
 
288
    return;
 
289
  assert((*semaphore_info)->signature == MagickSignature);
 
290
#if defined(HAVE_PTHREAD)
 
291
  (void) pthread_mutex_lock(&semaphore_mutex);
 
292
#endif
 
293
#if defined(WIN32)
 
294
#if !defined(USE_SPINLOCKS)
 
295
  if (!active_semaphore)
 
296
    InitializeCriticalSection(&semaphore_mutex);
 
297
  active_semaphore=True;
 
298
  EnterCriticalSection(&semaphore_mutex);
 
299
#else
 
300
  spinlock_wait(&semaphore_mutex);
 
301
#endif
 
302
#endif
 
303
#if defined(HAVE_PTHREAD)
 
304
  (void) pthread_mutex_destroy(&(*semaphore_info)->mutex);
 
305
#endif
 
306
#if defined(WIN32)
 
307
  DeleteCriticalSection(&(*semaphore_info)->mutex);
 
308
#endif
 
309
  MagickFreeMemory((*semaphore_info));
 
310
#if defined(HAVE_PTHREAD)
 
311
  (void) pthread_mutex_unlock(&semaphore_mutex);
 
312
#endif
 
313
#if defined(WIN32)
 
314
#if !defined(USE_SPINLOCKS)
 
315
  LeaveCriticalSection(&semaphore_mutex);
 
316
#else
 
317
  spinlock_release(&semaphore_mutex);
 
318
#endif
 
319
#endif
 
320
}
 
321
 
 
322
/*
 
323
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
324
%                                                                             %
 
325
%                                                                             %
 
326
%                                                                             %
 
327
%   I n i t i a l i z e S e m a p h o r e                                     %
 
328
%                                                                             %
 
329
%                                                                             %
 
330
%                                                                             %
 
331
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
332
%
 
333
%  Method InitializeSemaphore initializes the semaphore environment.
 
334
%
 
335
%  The format of the InitializeSemaphore method is:
 
336
%
 
337
%      InitializeSemaphore(void)
 
338
%
 
339
%
 
340
*/
 
341
MagickExport void InitializeSemaphore(void)
 
342
{
 
343
#if defined(HAVE_PTHREAD)
 
344
  (void) pthread_mutex_init(&semaphore_mutex,
 
345
    (const pthread_mutexattr_t *) NULL);
 
346
#endif
 
347
#if defined(WIN32)
 
348
#if !defined(USE_SPINLOCKS)
 
349
  if (!active_semaphore)
 
350
    InitializeCriticalSection(&semaphore_mutex);
 
351
  active_semaphore=True;
 
352
#endif
 
353
#endif
 
354
}
 
355
 
 
356
/*
 
357
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
358
%                                                                             %
 
359
%                                                                             %
 
360
%                                                                             %
 
361
%   L i b e r a t e S e m a p h o r e I n f o                                 %
 
362
%                                                                             %
 
363
%                                                                             %
 
364
%                                                                             %
 
365
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
366
%
 
367
%  Method LiberateSemaphoreInfo liberates a semaphore.
 
368
%
 
369
%  The format of the LiberateSemaphoreInfo method is:
 
370
%
 
371
%      LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
 
372
%
 
373
%  A description of each parameter follows:
 
374
%
 
375
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
 
376
%
 
377
%
 
378
*/
 
379
MagickExport void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
 
380
{
 
381
  assert(semaphore_info != (SemaphoreInfo **) NULL);
 
382
  if (*semaphore_info == (SemaphoreInfo *) NULL)
 
383
    return;
 
384
  assert((*semaphore_info)->signature == MagickSignature);
 
385
  (void) UnlockSemaphoreInfo(*semaphore_info);
 
386
}
 
387
 
 
388
/*
 
389
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
390
%                                                                             %
 
391
%                                                                             %
 
392
%                                                                             %
 
393
%   L o c k S e m a p h o r e I n f o                                         %
 
394
%                                                                             %
 
395
%                                                                             %
 
396
%                                                                             %
 
397
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
398
%
 
399
%  Method LockSemaphoreInfo locks a semaphore.
 
400
%
 
401
%  The format of the LockSemaphoreInfo method is:
 
402
%
 
403
%      unsigned int LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
 
404
%
 
405
%  A description of each parameter follows:
 
406
%
 
407
%    o status:  Method LockSemaphoreInfo returns True on success otherwise
 
408
%      False.
 
409
%
 
410
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
 
411
%
 
412
%
 
413
*/
 
414
MagickExport unsigned int LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
 
415
{
 
416
  assert(semaphore_info != (SemaphoreInfo *) NULL);
 
417
  assert(semaphore_info->signature == MagickSignature);
 
418
#if defined(HAVE_PTHREAD)
 
419
  if (pthread_mutex_lock(&semaphore_info->mutex))
 
420
    return(False);
 
421
  /* Record the thread ID of the locking thread */
 
422
  semaphore_info->thread_id=pthread_self();
 
423
#endif
 
424
#if defined(WIN32)
 
425
  EnterCriticalSection(&semaphore_info->mutex);
 
426
  /* Record the thread ID of the locking thread */
 
427
  semaphore_info->thread_id=GetCurrentThreadId();
 
428
#endif
 
429
  semaphore_info->locked=True;
 
430
  return(True);
 
431
}
 
432
 
 
433
/*
 
434
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
435
%                                                                             %
 
436
%                                                                             %
 
437
%                                                                             %
 
438
%   U n l o c k S e m a p h o r e I n f o                                     %
 
439
%                                                                             %
 
440
%                                                                             %
 
441
%                                                                             %
 
442
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
443
%
 
444
%  Method UnlockSemaphoreInfo unlocks a semaphore.
 
445
%
 
446
%  The format of the LockSemaphoreInfo method is:
 
447
%
 
448
%      unsigned int UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
 
449
%
 
450
%  A description of each parameter follows:
 
451
%
 
452
%    o status:  Method UnlockSemaphoreInfo returns True on success otherwise
 
453
%      False.
 
454
%
 
455
%    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
 
456
%
 
457
%
 
458
*/
 
459
MagickExport unsigned int UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
 
460
{
 
461
  assert(semaphore_info != (SemaphoreInfo *) NULL);
 
462
  assert(semaphore_info->signature == MagickSignature);
 
463
  if (semaphore_info->locked != True)
 
464
    return (False);
 
465
  semaphore_info->locked=False;
 
466
#if defined(HAVE_PTHREAD)
 
467
  /* Enforce that unlocking thread is the same as the locking thread */
 
468
  assert(pthread_equal(semaphore_info->thread_id,pthread_self()));
 
469
  if (pthread_mutex_unlock(&semaphore_info->mutex))
 
470
    return(False);
 
471
#endif
 
472
#if defined(WIN32)
 
473
  /* Enforce that unlocking thread is the same as the locking thread */
 
474
  assert(GetCurrentThreadId() == semaphore_info->thread_id);
 
475
  LeaveCriticalSection(&semaphore_info->mutex);
 
476
#endif
 
477
  return(True);
 
478
}