|
MagickCore
6.7.5
|
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 }