1 // This may look like C code, but it is really -*- C++ -*- 2 // 3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002 4 // Copyright Dirk Lemstra 2014-2015 5 // 6 // Implementation of thread support 7 // 8 9 #define MAGICKCORE_IMPLEMENTATION 1 10 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1 11 12 #include "Magick++/Thread.h" 13 #include "Magick++/Exception.h" 14 15 #include <string.h> 16 17 // Default constructor 18 Magick::MutexLock::MutexLock(void) 19 #if defined(MAGICKCORE_HAVE_PTHREAD) 20 // POSIX threads 21 : _mutex() 22 { 23 ::pthread_mutexattr_t 24 attr; 25 26 int 27 sysError; 28 29 if ((sysError=::pthread_mutexattr_init(&attr)) == 0) 30 if ((sysError=::pthread_mutex_init(&_mutex,&attr)) == 0) 31 { 32 ::pthread_mutexattr_destroy(&attr); 33 return; 34 } 35 throwExceptionExplicit(MagickCore::OptionError,"mutex initialization failed", 36 strerror(sysError)); 37 } 38 #else 39 #if defined(_VISUALC_) && defined(_MT) 40 // Win32 threads 41 { 42 SECURITY_ATTRIBUTES 43 security; 44 45 /* Allow the semaphore to be inherited */ 46 security.nLength=sizeof(security); 47 security.lpSecurityDescriptor=(LPVOID) NULL; 48 security.bInheritHandle=TRUE; 49 50 /* Create the semaphore, with initial value signaled */ 51 _mutex=::CreateSemaphore(&security,1,1,(LPCSTR) NULL); 52 if (_mutex != (HANDLE) NULL) 53 return; 54 throwExceptionExplicit(MagickCore::OptionError, 55 "mutex initialization failed"); 56 } 57 #else 58 // Threads not supported 59 { 60 } 61 #endif 62 #endif 63 64 // Destructor 65 Magick::MutexLock::~MutexLock(void) 66 { 67 #if defined(MAGICKCORE_HAVE_PTHREAD) 68 int 69 sysError; 70 71 if ((sysError=::pthread_mutex_destroy(&_mutex)) == 0) 72 return; 73 throwExceptionExplicit(MagickCore::OptionError,"mutex destruction failed", 74 strerror(sysError)); 75 #endif 76 #if defined(_MT) && defined(_VISUALC_) 77 if (::CloseHandle(_mutex) != 0) 78 return; 79 throwExceptionExplicit(MagickCore::OptionError,"mutex destruction failed"); 80 #endif 81 } 82 83 // Lock mutex 84 void Magick::MutexLock::lock(void) 85 { 86 #if defined(MAGICKCORE_HAVE_PTHREAD) 87 int 88 sysError; 89 90 if ((sysError=::pthread_mutex_lock(&_mutex)) == 0) 91 return; 92 throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed", 93 strerror(sysError)); 94 #endif 95 #if defined(_MT) && defined(_VISUALC_) 96 if (WaitForSingleObject(_mutex,INFINITE) != WAIT_FAILED) 97 return; 98 throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed"); 99 #endif 100 } 101 102 // Unlock mutex 103 void Magick::MutexLock::unlock(void) 104 { 105 #if defined(MAGICKCORE_HAVE_PTHREAD) 106 int 107 sysError; 108 109 if ((sysError=::pthread_mutex_unlock(&_mutex)) == 0) 110 return; 111 throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed", 112 strerror(sysError)); 113 #endif 114 #if defined(_MT) && defined(_VISUALC_) 115 if (ReleaseSemaphore(_mutex,1,(LPLONG) NULL) == TRUE) 116 return; 117 throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed"); 118 #endif 119 } 120