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
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 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
lock(void)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
unlock(void)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