/src/graphicsmagick/Magick++/lib/Thread.cpp
Line | Count | Source |
1 | | // This may look like C code, but it is really -*- C++ -*- |
2 | | // |
3 | | // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002 |
4 | | // |
5 | | // Implementation of thread support |
6 | | // |
7 | | |
8 | | #define MAGICK_IMPLEMENTATION |
9 | | #define MAGICK_PLUSPLUS_IMPLEMENTATION |
10 | | |
11 | | #include "Magick++/Thread.h" |
12 | | #include "Magick++/Exception.h" |
13 | | |
14 | | #include <string.h> |
15 | | |
16 | | // Default constructor |
17 | | Magick::MutexLock::MutexLock(void) |
18 | | #if defined(HasPTHREADS) |
19 | | // POSIX threads |
20 | | : _mutex() |
21 | | { |
22 | | ::pthread_mutexattr_t attr; |
23 | | int sysError; |
24 | | if ( (sysError = ::pthread_mutexattr_init( &attr )) == 0 ) |
25 | | if ( (sysError = ::pthread_mutex_init( &_mutex, &attr )) == 0 ) |
26 | | { |
27 | | ::pthread_mutexattr_destroy( &attr ); |
28 | | return; |
29 | | } |
30 | | throwExceptionExplicit( OptionError, "mutex initialization failed", |
31 | | strerror(sysError) ); |
32 | | } |
33 | | #else |
34 | | #if defined(_VISUALC_) && defined(_MT) |
35 | | // Win32 threads |
36 | | : _mutex() |
37 | | { |
38 | | SECURITY_ATTRIBUTES security; |
39 | | |
40 | | /* Allow the semaphore to be inherited */ |
41 | | security.nLength = sizeof(security); |
42 | | security.lpSecurityDescriptor = NULL; |
43 | | security.bInheritHandle = TRUE; |
44 | | |
45 | | /* Create the semaphore, with initial value signaled */ |
46 | | _mutex.id = ::CreateSemaphore(&security, 1, MAXSEMLEN, NULL); |
47 | | if ( _mutex.id != NULL ) |
48 | | return; |
49 | | throwExceptionExplicit( OptionError, "mutex initialization failed" ); |
50 | | } |
51 | | #else |
52 | | // Threads not supported |
53 | 1.16M | { |
54 | 1.16M | } |
55 | | #endif |
56 | | #endif |
57 | | |
58 | | // Destructor |
59 | | Magick::MutexLock::~MutexLock(void) |
60 | 1.16M | { |
61 | | #if defined(HasPTHREADS) |
62 | | int sysError; |
63 | | if ( (sysError = ::pthread_mutex_destroy( &_mutex )) == 0 ) |
64 | | return; |
65 | | throwExceptionExplicit( OptionError, "mutex destruction failed", |
66 | | strerror(sysError) ); |
67 | | #endif |
68 | | #if defined(_MT) && defined(_VISUALC_) |
69 | | if ( ::CloseHandle(_mutex.id) != 0 ) |
70 | | return; |
71 | | throwExceptionExplicit( OptionError, "mutex destruction failed" ); |
72 | | #endif |
73 | 1.16M | } |
74 | | |
75 | | // Lock mutex |
76 | | void Magick::MutexLock::lock(void) |
77 | 3.24M | { |
78 | | #if defined(HasPTHREADS) |
79 | | int sysError; |
80 | | if ( (sysError = ::pthread_mutex_lock( &_mutex )) == 0) |
81 | | return; |
82 | | throwExceptionExplicit( OptionError, "mutex lock failed", |
83 | | strerror(sysError)); |
84 | | #endif |
85 | | #if defined(_MT) && defined(_VISUALC_) |
86 | | #if 1 |
87 | | if (WaitForSingleObject(_mutex.id,INFINITE) != WAIT_FAILED) |
88 | | return; |
89 | | throwExceptionExplicit( OptionError, "mutex lock failed" ); |
90 | | #else |
91 | | // Following code is not known to work correctly yet. |
92 | | while(1) |
93 | | { |
94 | | DWORD status=MsgWaitForMultipleObjects(1, &_mutex.id, FALSE, INFINITE, |
95 | | QS_ALLEVENTS); |
96 | | // Loop if return was due to message received (which we don't care about). |
97 | | if (status == (WAIT_OBJECT_0+1)) |
98 | | continue; |
99 | | // If return was due to handle state change, then object is available. |
100 | | if ((status - WAIT_OBJECT_0) == 0) |
101 | | return; |
102 | | } |
103 | | // If we get here, then there was an unexpected return value. |
104 | | throwExceptionExplicit( OptionError, "mutex lock failed" ); |
105 | | #endif |
106 | | #endif |
107 | 3.24M | } |
108 | | |
109 | | // Unlock mutex |
110 | | void Magick::MutexLock::unlock(void) |
111 | 3.24M | { |
112 | | #if defined(HasPTHREADS) |
113 | | int sysError; |
114 | | if ( (sysError = ::pthread_mutex_unlock( &_mutex )) == 0) |
115 | | return; |
116 | | throwExceptionExplicit( OptionError, "mutex unlock failed", |
117 | | strerror(sysError) ); |
118 | | #endif |
119 | | #if defined(_MT) && defined(_VISUALC_) |
120 | | if ( ReleaseSemaphore(_mutex.id, 1, NULL) == TRUE ) |
121 | | return; |
122 | | throwExceptionExplicit( OptionError, "mutex unlock failed" ); |
123 | | #endif |
124 | 3.24M | } |