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