MagickCore  6.7.5
semaphore.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %        SSSSS  EEEEE  M   M   AAA   PPPP   H   H   OOO   RRRR   EEEEE        %
00007 %        SS     E      MM MM  A   A  P   P  H   H  O   O  R   R  E            %
00008 %         SSS   EEE    M M M  AAAAA  PPPP   HHHHH  O   O  RRRR   EEE          %
00009 %           SS  E      M   M  A   A  P      H   H  O   O  R R    E            %
00010 %        SSSSS  EEEEE  M   M  A   A  P      H   H   OOO   R  R   EEEEE        %
00011 %                                                                             %
00012 %                                                                             %
00013 %                        MagickCore Semaphore Methods                         %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                             William Radcliffe                               %
00017 %                                John Cristy                                  %
00018 %                                 June 2000                                   %
00019 %                                                                             %
00020 %                                                                             %
00021 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00022 %  dedicated to making software imaging solutions freely available.           %
00023 %                                                                             %
00024 %  You may not use this file except in compliance with the License.  You may  %
00025 %  obtain a copy of the License at                                            %
00026 %                                                                             %
00027 %    http://www.imagemagick.org/script/license.php                            %
00028 %                                                                             %
00029 %  Unless required by applicable law or agreed to in writing, software        %
00030 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00031 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00032 %  See the License for the specific language governing permissions and        %
00033 %  limitations under the License.                                             %
00034 %                                                                             %
00035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00036 %
00037 %
00038 %
00039 */
00040 
00041 /*
00042   Include declarations.
00043 */
00044 #include "MagickCore/studio.h"
00045 #include "MagickCore/exception.h"
00046 #include "MagickCore/exception-private.h"
00047 #include "MagickCore/memory_.h"
00048 #include "MagickCore/semaphore.h"
00049 #include "MagickCore/semaphore-private.h"
00050 #include "MagickCore/string_.h"
00051 #include "MagickCore/thread_.h"
00052 #include "MagickCore/thread-private.h"
00053 
00054 /*
00055   Struct declaractions.
00056 */
00057 struct SemaphoreInfo
00058 {
00059   MagickMutexType
00060     mutex;
00061 
00062   MagickThreadType
00063     id;
00064 
00065   ssize_t
00066     reference_count;
00067 
00068   size_t
00069     signature;
00070 };
00071 
00072 /*
00073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00074 %                                                                             %
00075 %                                                                             %
00076 %                                                                             %
00077 %   A c q u i r e S e m a p h o r e I n f o                                   %
00078 %                                                                             %
00079 %                                                                             %
00080 %                                                                             %
00081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00082 %
00083 %  AcquireSemaphoreInfo() acquires a semaphore.
00084 %
00085 %  The format of the AcquireSemaphoreInfo method is:
00086 %
00087 %      void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
00088 %
00089 %  A description of each parameter follows:
00090 %
00091 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00092 %
00093 */
00094 MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
00095 {
00096   assert(semaphore_info != (SemaphoreInfo **) NULL);
00097   if (*semaphore_info == (SemaphoreInfo *) NULL)
00098     {
00099       LockMagickMutex();
00100       if (*semaphore_info == (SemaphoreInfo *) NULL)
00101         *semaphore_info=AllocateSemaphoreInfo();
00102       UnlockMagickMutex();
00103     }
00104 }
00105 
00106 /*
00107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00108 %                                                                             %
00109 %                                                                             %
00110 %                                                                             %
00111 %   A l l o c a t e S e m a p h o r e I n f o                                 %
00112 %                                                                             %
00113 %                                                                             %
00114 %                                                                             %
00115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00116 %
00117 %  AllocateSemaphoreInfo() initializes the SemaphoreInfo structure.
00118 %
00119 %  The format of the AllocateSemaphoreInfo method is:
00120 %
00121 %      SemaphoreInfo *AllocateSemaphoreInfo(void)
00122 %
00123 */
00124 MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
00125 {
00126   SemaphoreInfo
00127     *semaphore_info;
00128 
00129   /*
00130     Allocate semaphore.
00131   */
00132   semaphore_info=(SemaphoreInfo *) malloc(sizeof(SemaphoreInfo));
00133   if (semaphore_info == (SemaphoreInfo *) NULL)
00134     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00135   (void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo));
00136   /*
00137     Initialize the semaphore.
00138   */
00139 #if defined(MAGICKCORE_THREAD_SUPPORT)
00140   {
00141     int
00142       status;
00143 
00144     pthread_mutexattr_t
00145       mutex_info;
00146 
00147     status=pthread_mutexattr_init(&mutex_info);
00148     if (status != 0)
00149       {
00150         errno=status;
00151         ThrowFatalException(ResourceLimitFatalError,
00152           "UnableToInitializeSemaphore");
00153       }
00154 #if defined(MAGICKCORE_DEBUG)
00155 #if defined(PTHREAD_MUTEX_ERRORCHECK)
00156     status=pthread_mutex_settype(&mutex_info,PTHREAD_MUTEX_ERRORCHECK);
00157     if (status != 0)
00158       {
00159         errno=status;
00160         ThrowFatalException(ResourceLimitFatalError,
00161           "UnableToInitializeSemaphore");
00162       }
00163 #endif
00164 #endif
00165     status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
00166     if (status != 0)
00167       {
00168         errno=status;
00169         ThrowFatalException(ResourceLimitFatalError,
00170           "UnableToInitializeSemaphore");
00171       }
00172     status=pthread_mutexattr_destroy(&mutex_info);
00173     if (status != 0)
00174       {
00175         errno=status;
00176         ThrowFatalException(ResourceLimitFatalError,
00177           "UnableToInitializeSemaphore");
00178       }
00179   }
00180 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00181   {
00182     int
00183       status;
00184 
00185     status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x0400);
00186     if (status == 0)
00187       {
00188         errno=status;
00189         ThrowFatalException(ResourceLimitFatalError,
00190           "UnableToInitializeSemaphore");
00191        }
00192   }
00193 #endif
00194   semaphore_info->id=GetMagickThreadId();
00195   semaphore_info->reference_count=0;
00196   semaphore_info->signature=MagickSignature;
00197   return(semaphore_info);
00198 }
00199 
00200 /*
00201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00202 %                                                                             %
00203 %                                                                             %
00204 %                                                                             %
00205 %   D e s t r o y S e m a p h o r e I n f o                                   %
00206 %                                                                             %
00207 %                                                                             %
00208 %                                                                             %
00209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00210 %
00211 %  DestroySemaphoreInfo() destroys a semaphore.
00212 %
00213 %  The format of the DestroySemaphoreInfo method is:
00214 %
00215 %      void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00216 %
00217 %  A description of each parameter follows:
00218 %
00219 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00220 %
00221 */
00222 MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00223 {
00224   assert(semaphore_info != (SemaphoreInfo **) NULL);
00225   assert((*semaphore_info) != (SemaphoreInfo *) NULL);
00226   assert((*semaphore_info)->signature == MagickSignature);
00227   LockMagickMutex();
00228 #if defined(MAGICKCORE_THREAD_SUPPORT)
00229   {
00230     int
00231       status;
00232 
00233     status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
00234     if (status != 0)
00235       {
00236         errno=status;
00237         ThrowFatalException(ResourceLimitFatalError,"UnableToDestroySemaphore");
00238       }
00239   }
00240 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00241   DeleteCriticalSection(&(*semaphore_info)->mutex);
00242 #endif
00243   (*semaphore_info)->signature=(~MagickSignature);
00244   free(*semaphore_info);
00245   *semaphore_info=(SemaphoreInfo *) NULL;
00246   UnlockMagickMutex();
00247 }
00248 
00249 /*
00250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00251 %                                                                             %
00252 %                                                                             %
00253 %                                                                             %
00254 %   L o c k S e m a p h o r e I n f o                                         %
00255 %                                                                             %
00256 %                                                                             %
00257 %                                                                             %
00258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00259 %
00260 %  LockSemaphoreInfo() locks a semaphore.
00261 %
00262 %  The format of the LockSemaphoreInfo method is:
00263 %
00264 %      void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00265 %
00266 %  A description of each parameter follows:
00267 %
00268 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00269 %
00270 */
00271 MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00272 {
00273   assert(semaphore_info != (SemaphoreInfo *) NULL);
00274   assert(semaphore_info->signature == MagickSignature);
00275 #if defined(MAGICKCORE_THREAD_SUPPORT)
00276   {
00277     int
00278       status;
00279 
00280     status=pthread_mutex_lock(&semaphore_info->mutex);
00281     if (status != 0)
00282       {
00283         errno=status;
00284         ThrowFatalException(ResourceLimitFatalError,"UnableToLockSemaphore");
00285       }
00286   }
00287 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00288   EnterCriticalSection(&semaphore_info->mutex);
00289 #endif
00290 #if defined(MAGICKCORE_DEBUG)
00291   if ((semaphore_info->reference_count > 0) &&
00292       (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
00293     {
00294       (void) FormatLocaleFile(stderr,"Warning: unexpected recursive lock!\n");
00295       (void) fflush(stderr);
00296     }
00297 #endif
00298   semaphore_info->id=GetMagickThreadId();
00299   semaphore_info->reference_count++;
00300 }
00301 
00302 /*
00303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00304 %                                                                             %
00305 %                                                                             %
00306 %                                                                             %
00307 %   R e l i n g u i s h S e m a p h o r e I n f o                             %
00308 %                                                                             %
00309 %                                                                             %
00310 %                                                                             %
00311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00312 %
00313 %  RelinquishSemaphoreInfo() relinquishes a semaphore.
00314 %
00315 %  The format of the RelinquishSemaphoreInfo method is:
00316 %
00317 %      RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00318 %
00319 %  A description of each parameter follows:
00320 %
00321 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00322 %
00323 */
00324 MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00325 {
00326   assert(semaphore_info != (SemaphoreInfo *) NULL);
00327   assert(semaphore_info->signature == MagickSignature);
00328   UnlockSemaphoreInfo(semaphore_info);
00329 }
00330 
00331 /*
00332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00333 %                                                                             %
00334 %                                                                             %
00335 %                                                                             %
00336 %   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                         %
00337 %                                                                             %
00338 %                                                                             %
00339 %                                                                             %
00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00341 %
00342 %  SemaphoreComponentGenesis() instantiates the semaphore environment.
00343 %
00344 %  The format of the SemaphoreComponentGenesis method is:
00345 %
00346 %      MagickBooleanType SemaphoreComponentGenesis(void)
00347 %
00348 */
00349 MagickPrivate MagickBooleanType SemaphoreComponentGenesis(void)
00350 {
00351   LockMagickMutex();
00352   UnlockMagickMutex();
00353   return(MagickTrue);
00354 }
00355 
00356 /*
00357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00358 %                                                                             %
00359 %                                                                             %
00360 %                                                                             %
00361 %   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                       %
00362 %                                                                             %
00363 %                                                                             %
00364 %                                                                             %
00365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00366 %
00367 %  SemaphoreComponentTerminus() destroys the semaphore component.
00368 %
00369 %  The format of the SemaphoreComponentTerminus method is:
00370 %
00371 %      SemaphoreComponentTerminus(void)
00372 %
00373 */
00374 MagickPrivate void SemaphoreComponentTerminus(void)
00375 {
00376 }
00377 
00378 /*
00379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00380 %                                                                             %
00381 %                                                                             %
00382 %                                                                             %
00383 %   U n l o c k S e m a p h o r e I n f o                                     %
00384 %                                                                             %
00385 %                                                                             %
00386 %                                                                             %
00387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00388 %
00389 %  UnlockSemaphoreInfo() unlocks a semaphore.
00390 %
00391 %  The format of the UnlockSemaphoreInfo method is:
00392 %
00393 %      void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00394 %
00395 %  A description of each parameter follows:
00396 %
00397 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00398 %
00399 */
00400 MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00401 {
00402   assert(semaphore_info != (SemaphoreInfo *) NULL);
00403   assert(semaphore_info->signature == MagickSignature);
00404 #if defined(MAGICKCORE_DEBUG)
00405   assert(IsMagickThreadEqual(semaphore_info->id) != MagickFalse);
00406   if (semaphore_info->reference_count == 0)
00407     {
00408       (void) FormatLocaleFile(stderr,
00409         "Warning: semaphore lock already unlocked!\n");
00410       (void) fflush(stderr);
00411       return;
00412     }
00413   semaphore_info->reference_count--;
00414 #endif
00415 #if defined(MAGICKCORE_THREAD_SUPPORT)
00416   {
00417     int
00418       status;
00419 
00420     status=pthread_mutex_unlock(&semaphore_info->mutex);
00421     if (status != 0)
00422       {
00423         errno=status;
00424         ThrowFatalException(ResourceLimitFatalError,"UnableToUnlockSemaphore");
00425       }
00426   }
00427 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00428   LeaveCriticalSection(&semaphore_info->mutex);
00429 #endif
00430 }