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-2009 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 "magick/studio.h"
00045 #include "magick/exception.h"
00046 #include "magick/exception-private.h"
00047 #include "magick/memory_.h"
00048 #include "magick/semaphore.h"
00049 #include "magick/string_.h"
00050 #include "magick/thread_.h"
00051 #include "magick/thread-private.h"
00052 
00053 /*
00054   Struct declaractions.
00055 */
00056 struct SemaphoreInfo
00057 {
00058   MagickMutexType
00059     mutex;
00060 
00061   MagickThreadType
00062     id;
00063 
00064   long
00065     reference_count;
00066 
00067   unsigned long
00068     signature;
00069 };
00070 
00071 /*
00072   Static declaractions.
00073 */
00074 #if defined(MAGICKCORE_HAVE_PTHREAD)
00075 static pthread_mutex_t
00076   semaphore_mutex = PTHREAD_MUTEX_INITIALIZER;
00077 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00078 static LONG
00079   semaphore_mutex = 0;
00080 #else
00081 static long
00082   semaphore_mutex = 0;
00083 #endif
00084 
00085 /*
00086   Forward declaractions.
00087 */
00088 static void
00089   LockMagickMutex(void),
00090   UnlockMagickMutex(void);
00091 
00092 /*
00093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00094 %                                                                             %
00095 %                                                                             %
00096 %                                                                             %
00097 %   A c q u i r e S e m a p h o r e I n f o                                   %
00098 %                                                                             %
00099 %                                                                             %
00100 %                                                                             %
00101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00102 %
00103 %  AcquireSemaphoreInfo() acquires a semaphore.
00104 %
00105 %  The format of the AcquireSemaphoreInfo method is:
00106 %
00107 %      void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
00108 %
00109 %  A description of each parameter follows:
00110 %
00111 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00112 %
00113 */
00114 MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
00115 {
00116   assert(semaphore_info != (SemaphoreInfo **) NULL);
00117   if (*semaphore_info == (SemaphoreInfo *) NULL)
00118     {
00119       LockMagickMutex();
00120       if (*semaphore_info == (SemaphoreInfo *) NULL)
00121         *semaphore_info=AllocateSemaphoreInfo();
00122       UnlockMagickMutex();
00123     }
00124 }
00125 
00126 /*
00127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00128 %                                                                             %
00129 %                                                                             %
00130 %                                                                             %
00131 %   A l l o c a t e S e m a p h o r e I n f o                                 %
00132 %                                                                             %
00133 %                                                                             %
00134 %                                                                             %
00135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00136 %
00137 %  AllocateSemaphoreInfo() initializes the SemaphoreInfo structure.
00138 %
00139 %  The format of the AllocateSemaphoreInfo method is:
00140 %
00141 %      SemaphoreInfo *AllocateSemaphoreInfo(void)
00142 %
00143 */
00144 MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
00145 {
00146   SemaphoreInfo
00147     *semaphore_info;
00148 
00149   /*
00150     Allocate semaphore.
00151   */
00152   semaphore_info=(SemaphoreInfo *) AcquireAlignedMemory(1,
00153     sizeof(SemaphoreInfo));
00154   if (semaphore_info == (SemaphoreInfo *) NULL)
00155     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00156   (void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo));
00157   /*
00158     Initialize the semaphore.
00159   */
00160 #if defined(MAGICKCORE_HAVE_PTHREAD)
00161   {
00162     int
00163       status;
00164 
00165     pthread_mutexattr_t
00166       mutex_info;
00167 
00168     status=pthread_mutexattr_init(&mutex_info);
00169     if (status != 0)
00170       {
00171         semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory(
00172           semaphore_info);
00173         ThrowFatalException(ResourceLimitFatalError,
00174           "UnableToInitializeSemaphore");
00175       }
00176     status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
00177     (void) pthread_mutexattr_destroy(&mutex_info);
00178     if (status != 0)
00179       {
00180         semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory(
00181           semaphore_info);
00182         ThrowFatalException(ResourceLimitFatalError,
00183           "UnableToInitializeSemaphore");
00184       }
00185   }
00186 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00187   InitializeCriticalSection(&semaphore_info->mutex);
00188 #endif
00189   semaphore_info->id=GetMagickThreadId();
00190   semaphore_info->reference_count=0;
00191   semaphore_info->signature=MagickSignature;
00192   return(semaphore_info);
00193 }
00194 
00195 /*
00196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00197 %                                                                             %
00198 %                                                                             %
00199 %                                                                             %
00200 %   D e s t r o y S e m a p h o r e I n f o                                   %
00201 %                                                                             %
00202 %                                                                             %
00203 %                                                                             %
00204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00205 %
00206 %  DestroySemaphoreInfo() destroys a semaphore.
00207 %
00208 %  The format of the DestroySemaphoreInfo method is:
00209 %
00210 %      void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00211 %
00212 %  A description of each parameter follows:
00213 %
00214 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00215 %
00216 */
00217 MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00218 {
00219   assert(semaphore_info != (SemaphoreInfo **) NULL);
00220   assert((*semaphore_info) != (SemaphoreInfo *) NULL);
00221   assert((*semaphore_info)->signature == MagickSignature);
00222   LockMagickMutex();
00223 #if defined(MAGICKCORE_HAVE_PTHREAD)
00224   (void) pthread_mutex_destroy(&(*semaphore_info)->mutex);
00225 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00226   DeleteCriticalSection(&(*semaphore_info)->mutex);
00227 #endif
00228   (*semaphore_info)->signature=(~MagickSignature);
00229   *semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory(*semaphore_info);
00230   UnlockMagickMutex();
00231 }
00232 
00233 /*
00234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00235 %                                                                             %
00236 %                                                                             %
00237 %                                                                             %
00238 +   L o c k M a g i c k M u t e x                                             %
00239 %                                                                             %
00240 %                                                                             %
00241 %                                                                             %
00242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00243 %
00244 %  LockMagickMutex() locks a global mutex.  If it is already locked, the
00245 %  calling thread blocks until the mutex becomes available.
00246 %
00247 %  The format of the LockMagickMutex method is:
00248 %
00249 %      void LockMagickMutex(void)
00250 %
00251 */
00252 static void LockMagickMutex(void)
00253 {
00254 #if defined(MAGICKCORE_HAVE_PTHREAD)
00255   if (pthread_mutex_lock(&semaphore_mutex) != 0)
00256     (void) fprintf(stderr,"pthread_mutex_lock failed %s\n",
00257       GetExceptionMessage(errno));
00258 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00259   while (InterlockedCompareExchange(&semaphore_mutex,1L,0L) != 0)
00260     Sleep(10);
00261 #endif
00262 }
00263 
00264 /*
00265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00266 %                                                                             %
00267 %                                                                             %
00268 %                                                                             %
00269 %   L o c k S e m a p h o r e I n f o                                         %
00270 %                                                                             %
00271 %                                                                             %
00272 %                                                                             %
00273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00274 %
00275 %  LockSemaphoreInfo() locks a semaphore.
00276 %
00277 %  The format of the LockSemaphoreInfo method is:
00278 %
00279 %      MagickBooleanType LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00280 %
00281 %  A description of each parameter follows:
00282 %
00283 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00284 %
00285 */
00286 MagickExport MagickBooleanType LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00287 {
00288   assert(semaphore_info != (SemaphoreInfo *) NULL);
00289 #if defined(MAGICKCORE_HAVE_PTHREAD)
00290   {
00291     int
00292       status;
00293 
00294     status=pthread_mutex_lock(&semaphore_info->mutex);
00295     if (status != 0)
00296       return(MagickFalse);
00297 #if defined(MAGICKCORE_DEBUG)
00298     {
00299       if ((semaphore_info->reference_count > 0) &&
00300           (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
00301         {
00302           (void) fprintf(stderr,"Warning: unexpected recursive lock!\n");
00303           (void) fflush(stderr);
00304         }
00305     }
00306 #endif
00307   }
00308 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00309   {
00310     EnterCriticalSection(&semaphore_info->mutex);
00311 #if defined(MAGICKCORE_DEBUG)
00312     {
00313       if ((semaphore_info->reference_count > 0) &&
00314           (IsMagickThreadEqual(semaphore_info->id) != MagickFalse))
00315         {
00316           (void) fprintf(stderr,"Warning: unexpected recursive lock!\n");
00317           (void) fflush(stderr);
00318         }
00319     }
00320 #endif
00321   }
00322 #endif
00323   semaphore_info->id=GetMagickThreadId();
00324   semaphore_info->reference_count++;
00325   return(MagickTrue);
00326 }
00327 
00328 /*
00329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00330 %                                                                             %
00331 %                                                                             %
00332 %                                                                             %
00333 %   R e l i n g u i s h S e m a p h o r e I n f o                             %
00334 %                                                                             %
00335 %                                                                             %
00336 %                                                                             %
00337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00338 %
00339 %  RelinquishSemaphoreInfo() relinquishes a semaphore.
00340 %
00341 %  The format of the RelinquishSemaphoreInfo method is:
00342 %
00343 %      RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00344 %
00345 %  A description of each parameter follows:
00346 %
00347 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00348 %
00349 */
00350 MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00351 {
00352   assert(semaphore_info != (SemaphoreInfo *) NULL);
00353   assert(semaphore_info->signature == MagickSignature);
00354   (void) UnlockSemaphoreInfo(semaphore_info);
00355 }
00356 
00357 /*
00358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00359 %                                                                             %
00360 %                                                                             %
00361 %                                                                             %
00362 %   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                         %
00363 %                                                                             %
00364 %                                                                             %
00365 %                                                                             %
00366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00367 %
00368 %  SemaphoreComponentGenesis() instantiates the semaphore environment.
00369 %
00370 %  The format of the SemaphoreComponentGenesis method is:
00371 %
00372 %      MagickBooleanType SemaphoreComponentGenesis(void)
00373 %
00374 */
00375 MagickExport MagickBooleanType SemaphoreComponentGenesis(void)
00376 {
00377   LockMagickMutex();
00378   UnlockMagickMutex();
00379   return(MagickTrue);
00380 }
00381 
00382 /*
00383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00384 %                                                                             %
00385 %                                                                             %
00386 %                                                                             %
00387 %   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                       %
00388 %                                                                             %
00389 %                                                                             %
00390 %                                                                             %
00391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00392 %
00393 %  SemaphoreComponentTerminus() destroys the semaphore component.
00394 %
00395 %  The format of the SemaphoreComponentTerminus method is:
00396 %
00397 %      SemaphoreComponentTerminus(void)
00398 %
00399 */
00400 MagickExport void SemaphoreComponentTerminus(void)
00401 {
00402 }
00403 
00404 /*
00405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00406 %                                                                             %
00407 %                                                                             %
00408 %                                                                             %
00409 +   U n l o c k M a g i c k M u t e x                                         %
00410 %                                                                             %
00411 %                                                                             %
00412 %                                                                             %
00413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00414 %
00415 %  UnlockMagickMutex() releases a global mutex.
00416 %
00417 %  The format of the LockMagickMutex method is:
00418 %
00419 %      void UnlockMagickMutex(void)
00420 %
00421 */
00422 static void UnlockMagickMutex(void)
00423 {
00424 #if defined(MAGICKCORE_HAVE_PTHREAD)
00425   if (pthread_mutex_unlock(&semaphore_mutex) != 0)
00426     (void) fprintf(stderr,"pthread_mutex_unlock failed %s\n",
00427       GetExceptionMessage(errno));
00428 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00429   InterlockedExchange(&semaphore_mutex,0L);
00430 #endif
00431 }
00432 
00433 /*
00434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00435 %                                                                             %
00436 %                                                                             %
00437 %                                                                             %
00438 %   U n l o c k S e m a p h o r e I n f o                                     %
00439 %                                                                             %
00440 %                                                                             %
00441 %                                                                             %
00442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00443 %
00444 %  UnlockSemaphoreInfo() unlocks a semaphore.
00445 %
00446 %  The format of the UnlockSemaphoreInfo method is:
00447 %
00448 %      MagickBooleanType UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00449 %
00450 %  A description of each parameter follows:
00451 %
00452 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00453 %
00454 */
00455 MagickExport MagickBooleanType UnlockSemaphoreInfo(
00456   SemaphoreInfo *semaphore_info)
00457 {
00458   assert(semaphore_info != (SemaphoreInfo *) NULL);
00459 #if defined(MAGICKCORE_DEBUG)
00460   assert(IsMagickThreadEqual(semaphore_info->id) != MagickFalse);
00461   if (semaphore_info->reference_count == 0)
00462     {
00463       (void) fprintf(stderr,"Warning: semaphore lock already unlocked!\n");
00464       (void) fflush(stderr);
00465       return(MagickFalse);
00466     }
00467   semaphore_info->reference_count--;
00468 #endif
00469 #if defined(MAGICKCORE_HAVE_PTHREAD)
00470   {
00471     int
00472       status;
00473 
00474     status=pthread_mutex_unlock(&semaphore_info->mutex);
00475     if (status != 0)
00476       {
00477         semaphore_info->reference_count++;
00478         return(MagickFalse);
00479       }
00480   }
00481 #elif defined(MAGICKCORE_HAVE_WINTHREADS)
00482   LeaveCriticalSection(&semaphore_info->mutex);
00483 #endif
00484   return(MagickTrue);
00485 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1