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 18Magick::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 65Magick::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 84void 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 103void 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