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-2017
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
MutexLock(void)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
~MutexLock(void)65 Magick::MutexLock::~MutexLock(void)
66 {
67 #if defined(MAGICKCORE_HAVE_PTHREAD)
68 (void) ::pthread_mutex_destroy(&_mutex);
69 #endif
70 #if defined(_MT) && defined(_VISUALC_)
71 (void) ::CloseHandle(_mutex);
72 #endif
73 }
74
75 // Lock mutex
lock(void)76 void Magick::MutexLock::lock(void)
77 {
78 #if defined(MAGICKCORE_HAVE_PTHREAD)
79 int
80 sysError;
81
82 if ((sysError=::pthread_mutex_lock(&_mutex)) == 0)
83 return;
84 throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed",
85 strerror(sysError));
86 #endif
87 #if defined(_MT) && defined(_VISUALC_)
88 if (WaitForSingleObject(_mutex,INFINITE) != WAIT_FAILED)
89 return;
90 throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed");
91 #endif
92 }
93
94 // Unlock mutex
unlock(void)95 void Magick::MutexLock::unlock(void)
96 {
97 #if defined(MAGICKCORE_HAVE_PTHREAD)
98 int
99 sysError;
100
101 if ((sysError=::pthread_mutex_unlock(&_mutex)) == 0)
102 return;
103 throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed",
104 strerror(sysError));
105 #endif
106 #if defined(_MT) && defined(_VISUALC_)
107 if (ReleaseSemaphore(_mutex,1,(LPLONG) NULL) == TRUE)
108 return;
109 throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed");
110 #endif
111 }
112