WizardsToolkit  1.0.7
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 %                        WizardCore Semaphore Methods                         %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                             William Radcliffe                               %
00017 %                                John Cristy                                  %
00018 %                                 June 2000                                   %
00019 %                                                                             %
00020 %                                                                             %
00021 %  Copyright 1999-2011 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.wizards-toolkit.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 "wizard/studio.h"
00045 #include "wizard/exception.h"
00046 #include "wizard/exception-private.h"
00047 #include "wizard/memory_.h"
00048 #include "wizard/semaphore.h"
00049 #include "wizard/semaphore-private.h"
00050 #include "wizard/string_.h"
00051 #include "wizard/thread_.h"
00052 #include "wizard/thread-private.h"
00053 
00054 /*
00055   Struct declaractions.
00056 */
00057 struct SemaphoreInfo
00058 {
00059   WizardMutexType
00060     mutex;
00061 
00062   WizardThreadType
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 WizardExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
00095 {
00096   assert(semaphore_info != (SemaphoreInfo **) NULL);
00097   if (*semaphore_info == (SemaphoreInfo *) NULL)
00098     {
00099       LockWizardMutex();
00100       if (*semaphore_info == (SemaphoreInfo *) NULL)
00101         *semaphore_info=AllocateSemaphoreInfo();
00102       UnlockWizardMutex();
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 WizardExport 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(ResourceFatalError,"memory allocation failed `%s'");
00135   (void) ResetWizardMemory(semaphore_info,0,sizeof(SemaphoreInfo));
00136   /*
00137     Initialize the semaphore.
00138   */
00139 #if defined(WIZARDSTOOLKIT_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(ResourceFatalError,
00152           "unable to instantiate semaphore `%s'");
00153       }
00154     status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info);
00155     if (status != 0)
00156       {
00157         errno=status;
00158         ThrowFatalException(ResourceFatalError,
00159           "unable to instantiate semaphore `%s'");
00160       }
00161     status=pthread_mutexattr_destroy(&mutex_info);
00162     if (status != 0)
00163       {
00164         errno=status;
00165         ThrowFatalException(ResourceFatalError,
00166           "unable to instantiate semaphore `%s'");
00167       }
00168   }
00169 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
00170   {
00171     int
00172       status;
00173 
00174     status=InitializeCriticalSectionAndSpinCount(&semaphore_info->mutex,0x400);
00175     if (status == 0)
00176       {
00177         errno=status;
00178         ThrowFatalException(ResourceFatalError,
00179           "unable to instantiate semaphore `%s'");
00180       }
00181   }
00182 #endif
00183   semaphore_info->id=GetWizardThreadId();
00184   semaphore_info->reference_count=0;
00185   semaphore_info->signature=WizardSignature;
00186   return(semaphore_info);
00187 }
00188 
00189 /*
00190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00191 %                                                                             %
00192 %                                                                             %
00193 %                                                                             %
00194 %   D e s t r o y S e m a p h o r e I n f o                                   %
00195 %                                                                             %
00196 %                                                                             %
00197 %                                                                             %
00198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00199 %
00200 %  DestroySemaphoreInfo() destroys a semaphore.
00201 %
00202 %  The format of the DestroySemaphoreInfo method is:
00203 %
00204 %      void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00205 %
00206 %  A description of each parameter follows:
00207 %
00208 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00209 %
00210 */
00211 WizardExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
00212 {
00213   assert(semaphore_info != (SemaphoreInfo **) NULL);
00214   assert((*semaphore_info) != (SemaphoreInfo *) NULL);
00215   assert((*semaphore_info)->signature == WizardSignature);
00216   LockWizardMutex();
00217 #if defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
00218   {
00219     int
00220       status;
00221 
00222     status=pthread_mutex_destroy(&(*semaphore_info)->mutex);
00223     if (status != 0)
00224       {
00225         errno=status;
00226         ThrowFatalException(ResourceFatalError,
00227           "unable to destroy semaphore `%s'");
00228       }
00229   }
00230 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
00231   DeleteCriticalSection(&(*semaphore_info)->mutex);
00232 #endif
00233   (*semaphore_info)->signature=(~WizardSignature);
00234   free(*semaphore_info);
00235   *semaphore_info=(SemaphoreInfo *) NULL;
00236   UnlockWizardMutex();
00237 }
00238 
00239 /*
00240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00241 %                                                                             %
00242 %                                                                             %
00243 %                                                                             %
00244 %   L o c k S e m a p h o r e I n f o                                         %
00245 %                                                                             %
00246 %                                                                             %
00247 %                                                                             %
00248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00249 %
00250 %  LockSemaphoreInfo() locks a semaphore.
00251 %
00252 %  The format of the LockSemaphoreInfo method is:
00253 %
00254 %      void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00255 %
00256 %  A description of each parameter follows:
00257 %
00258 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00259 %
00260 */
00261 WizardExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00262 {
00263   assert(semaphore_info != (SemaphoreInfo *) NULL);
00264   assert(semaphore_info->signature == WizardSignature);
00265 #if defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
00266   {
00267     int
00268       status;
00269 
00270     status=pthread_mutex_lock(&semaphore_info->mutex);
00271     if (status != 0)
00272       {
00273         errno=status;
00274         ThrowFatalException(ResourceFatalError,
00275           "unable to lock semaphore `%s'");
00276       }
00277   }
00278 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
00279   EnterCriticalSection(&semaphore_info->mutex);
00280 #endif
00281 #if defined(WIZARDSTOOLKIT_DEBUG)
00282   if ((semaphore_info->reference_count > 0) &&
00283       (IsWizardThreadEqual(semaphore_info->id) != WizardFalse))
00284     {
00285       (void) fprintf(stderr,"Warning: unexpected recursive lock!\n");
00286       (void) fflush(stderr);
00287     }
00288 #endif
00289   semaphore_info->id=GetWizardThreadId();
00290   semaphore_info->reference_count++;
00291 }
00292 
00293 /*
00294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00295 %                                                                             %
00296 %                                                                             %
00297 %                                                                             %
00298 %   R e l i n g u i s h S e m a p h o r e I n f o                             %
00299 %                                                                             %
00300 %                                                                             %
00301 %                                                                             %
00302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00303 %
00304 %  RelinquishSemaphoreInfo() relinquishes a semaphore.
00305 %
00306 %  The format of the RelinquishSemaphoreInfo method is:
00307 %
00308 %      RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00309 %
00310 %  A description of each parameter follows:
00311 %
00312 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00313 %
00314 */
00315 WizardExport void RelinquishSemaphoreInfo(SemaphoreInfo *semaphore_info)
00316 {
00317   assert(semaphore_info != (SemaphoreInfo *) NULL);
00318   assert(semaphore_info->signature == WizardSignature);
00319   UnlockSemaphoreInfo(semaphore_info);
00320 }
00321 
00322 /*
00323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00324 %                                                                             %
00325 %                                                                             %
00326 %                                                                             %
00327 %   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                         %
00328 %                                                                             %
00329 %                                                                             %
00330 %                                                                             %
00331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00332 %
00333 %  SemaphoreComponentGenesis() instantiates the semaphore component.
00334 %
00335 %  The format of the SemaphoreComponentGenesis method is:
00336 %
00337 %      WizardBooleanType SemaphoreComponentGenesis(void)
00338 %
00339 */
00340 WizardExport WizardBooleanType SemaphoreComponentGenesis(void)
00341 {
00342   LockWizardMutex();
00343   UnlockWizardMutex();
00344   return(WizardTrue);
00345 }
00346 
00347 /*
00348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00349 %                                                                             %
00350 %                                                                             %
00351 %                                                                             %
00352 %   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                       %
00353 %                                                                             %
00354 %                                                                             %
00355 %                                                                             %
00356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00357 %
00358 %  SemaphoreComponentTerminus() destroys the semaphore environment.
00359 %
00360 %  The format of the SemaphoreComponentTerminus method is:
00361 %
00362 %      SemaphoreComponentTerminus(void)
00363 %
00364 */
00365 WizardExport void SemaphoreComponentTerminus(void)
00366 {
00367 }
00368 
00369 /*
00370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00371 %                                                                             %
00372 %                                                                             %
00373 %                                                                             %
00374 %   U n l o c k S e m a p h o r e I n f o                                     %
00375 %                                                                             %
00376 %                                                                             %
00377 %                                                                             %
00378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00379 %
00380 %  UnlockSemaphoreInfo() unlocks a semaphore.
00381 %
00382 %  The format of the UnlockSemaphoreInfo method is:
00383 %
00384 %      void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00385 %
00386 %  A description of each parameter follows:
00387 %
00388 %    o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
00389 %
00390 */
00391 WizardExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
00392 {
00393   assert(semaphore_info != (SemaphoreInfo *) NULL);
00394   assert(semaphore_info->signature == WizardSignature); 
00395 #if defined(WIZARDSTOOLKIT_DEBUG)
00396   assert(IsWizardThreadEqual(semaphore_info->id) != WizardFalse);
00397   if (semaphore_info->reference_count == 0)
00398     {
00399       (void) fprintf(stderr,"Warning: semaphore lock already unlocked!\n");
00400       (void) fflush(stderr);
00401       return;
00402     }
00403   semaphore_info->reference_count--;
00404 #endif
00405 #if defined(WIZARDSTOOLKIT_THREAD_SUPPORT)
00406   {
00407     int
00408       status;
00409 
00410     status=pthread_mutex_unlock(&semaphore_info->mutex);
00411     if (status != 0)
00412       {
00413         errno=status;
00414         ThrowFatalException(ResourceFatalError,
00415           "unable to unlock semaphore `%s'");
00416       }
00417   }
00418 #elif defined(WIZARDSTOOLKIT_HAVE_WINTHREADS)
00419   LeaveCriticalSection(&semaphore_info->mutex);
00420 #endif
00421 }