| /* |
| Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization |
| dedicated to making software imaging solutions freely available. |
| |
| You may not use this file except in compliance with the License. You may |
| obtain a copy of the License at |
| |
| https://imagemagick.org/script/license.php |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| MagickCore methods to synchronize code within a translation unit. |
| */ |
| #ifndef MAGICKCORE_MUTEX_H |
| #define MAGICKCORE_MUTEX_H |
| |
| #if defined(__cplusplus) || defined(c_plusplus) |
| extern "C" { |
| #endif |
| |
| /* |
| When included in a translation unit, the following code provides the |
| translation unit a means by which to synchronize multiple threads that might |
| try to enter the same critical section or to access a shared resource; it can |
| be included in multiple translation units, and thereby provide a separate, |
| independent means of synchronization to each such translation unit. |
| */ |
| |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| static MagickBooleanType |
| translation_unit_initialized = MagickFalse; |
| |
| static omp_lock_t |
| translation_unit_mutex; |
| #elif defined(MAGICKCORE_THREAD_SUPPORT) |
| static pthread_mutex_t |
| translation_unit_mutex = PTHREAD_MUTEX_INITIALIZER; |
| #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
| static LONG |
| translation_unit_mutex = 0; |
| #endif |
| |
| static inline void DestroyMagickMutex(void) |
| { |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| omp_destroy_lock(&translation_unit_mutex); |
| translation_unit_initialized=MagickFalse; |
| #endif |
| } |
| |
| static inline void InitializeMagickMutex(void) |
| { |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| omp_init_lock(&translation_unit_mutex); |
| translation_unit_initialized=MagickTrue; |
| #endif |
| } |
| |
| static inline void LockMagickMutex(void) |
| { |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| if (translation_unit_initialized == MagickFalse) |
| InitializeMagickMutex(); |
| omp_set_lock(&translation_unit_mutex); |
| #elif defined(MAGICKCORE_THREAD_SUPPORT) |
| { |
| int |
| status; |
| |
| status=pthread_mutex_lock(&translation_unit_mutex); |
| if (status != 0) |
| { |
| errno=status; |
| ThrowFatalException(ResourceLimitFatalError,"UnableToLockSemaphore"); |
| } |
| } |
| #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
| while (InterlockedCompareExchange(&translation_unit_mutex,1L,0L) != 0) |
| Sleep(10); |
| #endif |
| } |
| |
| static inline void UnlockMagickMutex(void) |
| { |
| #if defined(MAGICKCORE_OPENMP_SUPPORT) |
| omp_unset_lock(&translation_unit_mutex); |
| #elif defined(MAGICKCORE_THREAD_SUPPORT) |
| { |
| int |
| status; |
| |
| status=pthread_mutex_unlock(&translation_unit_mutex); |
| if (status != 0) |
| { |
| errno=status; |
| ThrowFatalException(ResourceLimitFatalError,"UnableToUnlockSemaphore"); |
| } |
| } |
| #elif defined(MAGICKCORE_WINDOWS_SUPPORT) |
| InterlockedExchange(&translation_unit_mutex,0L); |
| #endif |
| } |
| |
| #if defined(__cplusplus) || defined(c_plusplus) |
| } |
| #endif |
| |
| #endif |