]> granicus.if.org Git - imagemagick/blob - MagickCore/semaphore.c
(no commit message)
[imagemagick] / MagickCore / semaphore.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
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        %
11 %                                                                             %
12 %                                                                             %
13 %                        MagickCore Semaphore Methods                         %
14 %                                                                             %
15 %                              Software Design                                %
16 %                             William Radcliffe                               %
17 %                                John Cristy                                  %
18 %                                 June 2000                                   %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
22 %  dedicated to making software imaging solutions freely available.           %
23 %                                                                             %
24 %  You may not use this file except in compliance with the License.  You may  %
25 %  obtain a copy of the License at                                            %
26 %                                                                             %
27 %    http://www.imagemagick.org/script/license.php                            %
28 %                                                                             %
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.                                             %
34 %                                                                             %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 %
39 */
40 \f
41 /*
42   Include declarations.
43 */
44 #include "MagickCore/studio.h"
45 #include "MagickCore/exception.h"
46 #include "MagickCore/exception-private.h"
47 #include "MagickCore/memory_.h"
48 #include "MagickCore/semaphore.h"
49 #include "MagickCore/semaphore-private.h"
50 #include "MagickCore/string_.h"
51 #include "MagickCore/thread_.h"
52 #include "MagickCore/thread-private.h"
53 \f
54 /*
55   Struct declaractions.
56 */
57 struct SemaphoreInfo
58 {
59   MagickMutexType
60     mutex;
61
62   MagickThreadType
63     id;
64
65   ssize_t
66     reference_count;
67
68   size_t
69     signature;
70 };
71 \f
72 /*
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74 %                                                                             %
75 %                                                                             %
76 %                                                                             %
77 %   A c q u i r e S e m a p h o r e I n f o                                   %
78 %                                                                             %
79 %                                                                             %
80 %                                                                             %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 %
83 %  AcquireSemaphoreInfo() acquires a semaphore.
84 %
85 %  The format of the AcquireSemaphoreInfo method is:
86 %
87 %      void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
88 %
89 %  A description of each parameter follows:
90 %
91 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
92 %
93 */
94 MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
95 {
96   assert(semaphore_info != (SemaphoreInfo **) NULL);
97   if (*semaphore_info == (SemaphoreInfo *) NULL)
98     {
99       LockMagickMutex();
100       if (*semaphore_info == (SemaphoreInfo *) NULL)
101         *semaphore_info=AllocateSemaphoreInfo();
102       UnlockMagickMutex();
103     }
104 }
105 \f
106 /*
107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 %                                                                             %
109 %                                                                             %
110 %                                                                             %
111 %   A l l o c a t e S e m a p h o r e I n f o                                 %
112 %                                                                             %
113 %                                                                             %
114 %                                                                             %
115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 %
117 %  AllocateSemaphoreInfo() initializes the SemaphoreInfo structure.
118 %
119 %  The format of the AllocateSemaphoreInfo method is:
120 %
121 %      SemaphoreInfo *AllocateSemaphoreInfo(void)
122 %
123 */
124 MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
125 {
126   SemaphoreInfo
127     *semaphore_info;
128
129   /*
130     Allocate semaphore.
131   */
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));
136   /*
137     Initialize the semaphore.
138   */
139 #if defined(MAGICKCORE_THREAD_SUPPORT)
140   {
141     int
142       status;
143
144     pthread_mutexattr_t
145       mutex_info;
146
147     status=pthread_mutexattr_init(&mutex_info);
148     if (status != 0)
149       {
150         errno=status;
151         ThrowFatalException(ResourceLimitFatalError,
152           "UnableToInitializeSemaphore");
153       }
154     status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
155     if (status != 0)
156       {
157         errno=status;
158         ThrowFatalException(ResourceLimitFatalError,
159           "UnableToInitializeSemaphore");
160       }
161     status=pthread_mutexattr_destroy(&mutex_info);
162     if (status != 0)
163       {
164         errno=status;
165         ThrowFatalException(ResourceLimitFatalError,
166           "UnableToInitializeSemaphore");
167       }
168   }
169 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
170   {
171     int
172       status;
173
174     status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400);
175     if (status == 0)
176       {
177         errno=status;
178         ThrowFatalException(ResourceLimitFatalError,
179           "UnableToInitializeSemaphore");
180        }
181   }
182 #endif
183   semaphore_info->id=GetMagickThreadId();
184   semaphore_info->reference_count=0;
185   semaphore_info->signature=MagickSignature;
186   return(semaphore_info);
187 }
188 \f
189 /*
190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 %                                                                             %
192 %                                                                             %
193 %                                                                             %
194 %   D e s t r o y S e m a p h o r e I n f o                                   %
195 %                                                                             %
196 %                                                                             %
197 %                                                                             %
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 %
200 %  DestroySemaphoreInfo() destroys a semaphore.
201 %
202 %  The format of the DestroySemaphoreInfo method is:
203 %
204 %      void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
205 %
206 %  A description of each parameter follows:
207 %
208 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
209 %
210 */
211 MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
212 {
213   assert(semaphore_info != (SemaphoreInfo **) NULL);
214   assert((*semaphore_info) != (SemaphoreInfo *) NULL);
215   assert((*semaphore_info)->signature == MagickSignature);
216   LockMagickMutex();
217 #if defined(MAGICKCORE_THREAD_SUPPORT)
218   {
219     int
220       status;
221
222     status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
223     if (status != 0)
224       {
225         errno=status;
226         ThrowFatalException(ResourceLimitFatalError,"UnableToDestroySemaphore");
227       }
228   }
229 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
230   DeleteCriticalSection(&(*semaphore_info)->mutex);
231 #endif
232   (*semaphore_info)->signature=(~MagickSignature);
233   free(*semaphore_info);
234   *semaphore_info=(SemaphoreInfo *) NULL;
235   UnlockMagickMutex();
236 }
237 \f
238 /*
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 %                                                                             %
241 %                                                                             %
242 %                                                                             %
243 %   L o c k S e m a p h o r e I n f o                                         %
244 %                                                                             %
245 %                                                                             %
246 %                                                                             %
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248 %
249 %  LockSemaphoreInfo() locks a semaphore.
250 %
251 %  The format of the LockSemaphoreInfo method is:
252 %
253 %      void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
254 %
255 %  A description of each parameter follows:
256 %
257 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
258 %
259 */
260 MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
261 {
262   assert(semaphore_info != (SemaphoreInfo *) NULL);
263   assert(semaphore_info->signature == MagickSignature);
264 #if defined(MAGICKCORE_THREAD_SUPPORT)
265   {
266     int
267       status;
268
269     status=pthread_mutex_lock(&semaphore_info->mutex);
270     if (status != 0)
271       {
272         errno=status;
273         ThrowFatalException(ResourceLimitFatalError,"UnableToLockSemaphore");
274       }
275   }
276 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
277   EnterCriticalSection(&semaphore_info->mutex);
278 #endif
279 #if defined(MAGICKCORE_DEBUG)
280   if ((semaphore_info->reference_count > 0) &&
281       (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
282     {
283       (void) FormatLocaleFile(stderr,"Warning: unexpected recursive lock!\n");
284       (void) fflush(stderr);
285     }
286 #endif
287   semaphore_info->id=GetMagickThreadId();
288   semaphore_info->reference_count++;
289 }
290 \f
291 /*
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 %                                                                             %
294 %                                                                             %
295 %                                                                             %
296 %   R e l i n g u i s h S e m a p h o r e I n f o                             %
297 %                                                                             %
298 %                                                                             %
299 %                                                                             %
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 %
302 %  RelinquishSemaphoreInfo() relinquishes a semaphore.
303 %
304 %  The format of the RelinquishSemaphoreInfo method is:
305 %
306 %      RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
307 %
308 %  A description of each parameter follows:
309 %
310 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
311 %
312 */
313 MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
314 {
315   assert(semaphore_info != (SemaphoreInfo *) NULL);
316   assert(semaphore_info->signature == MagickSignature);
317   UnlockSemaphoreInfo(semaphore_info);
318 }
319 \f
320 /*
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322 %                                                                             %
323 %                                                                             %
324 %                                                                             %
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                         %
326 %                                                                             %
327 %                                                                             %
328 %                                                                             %
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330 %
331 %  SemaphoreComponentGenesis() instantiates the semaphore environment.
332 %
333 %  The format of the SemaphoreComponentGenesis method is:
334 %
335 %      MagickBooleanType SemaphoreComponentGenesis(void)
336 %
337 */
338 MagickExport MagickBooleanType SemaphoreComponentGenesis(void)
339 {
340   LockMagickMutex();
341   UnlockMagickMutex();
342   return(MagickTrue);
343 }
344 \f
345 /*
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 %                                                                             %
348 %                                                                             %
349 %                                                                             %
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                       %
351 %                                                                             %
352 %                                                                             %
353 %                                                                             %
354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 %
356 %  SemaphoreComponentTerminus() destroys the semaphore component.
357 %
358 %  The format of the SemaphoreComponentTerminus method is:
359 %
360 %      SemaphoreComponentTerminus(void)
361 %
362 */
363 MagickExport void SemaphoreComponentTerminus(void)
364 {
365 }
366 \f
367 /*
368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 %                                                                             %
370 %                                                                             %
371 %                                                                             %
372 %   U n l o c k S e m a p h o r e I n f o                                     %
373 %                                                                             %
374 %                                                                             %
375 %                                                                             %
376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377 %
378 %  UnlockSemaphoreInfo() unlocks a semaphore.
379 %
380 %  The format of the UnlockSemaphoreInfo method is:
381 %
382 %      void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
383 %
384 %  A description of each parameter follows:
385 %
386 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
387 %
388 */
389 MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
390 {
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)
396     {
397       (void) FormatLocaleFile(stderr,
398         "Warning: semaphore lock already unlocked!\n");
399       (void) fflush(stderr);
400       return;
401     }
402   semaphore_info->reference_count--;
403 #endif
404 #if defined(MAGICKCORE_THREAD_SUPPORT)
405   {
406     int
407       status;
408
409     status=pthread_mutex_unlock(&semaphore_info->mutex);
410     if (status != 0)
411       {
412         errno=status;
413         ThrowFatalException(ResourceLimitFatalError,"UnableToUnlockSemaphore");
414       }
415   }
416 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
417   LeaveCriticalSection(&semaphore_info->mutex);
418 #endif
419 }