blob: b89e9b8bf022b6afe56343d2e7b79c7265a8ea6a [file] [log] [blame]
// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
// Copyright Dirk Lemstra 2014-2017
//
// Implementation of thread support
//
#define MAGICKCORE_IMPLEMENTATION 1
#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
#include "Magick++/Thread.h"
#include "Magick++/Exception.h"
#include <string.h>
// Default constructor
Magick::MutexLock::MutexLock(void)
#if defined(MAGICKCORE_HAVE_PTHREAD)
// POSIX threads
: _mutex()
{
::pthread_mutexattr_t
attr;
int
sysError;
if ((sysError=::pthread_mutexattr_init(&attr)) == 0)
if ((sysError=::pthread_mutex_init(&_mutex,&attr)) == 0)
{
::pthread_mutexattr_destroy(&attr);
return;
}
throwExceptionExplicit(MagickCore::OptionError,"mutex initialization failed",
strerror(sysError));
}
#else
#if defined(_VISUALC_) && defined(_MT)
// Win32 threads
{
SECURITY_ATTRIBUTES
security;
/* Allow the semaphore to be inherited */
security.nLength=sizeof(security);
security.lpSecurityDescriptor=(LPVOID) NULL;
security.bInheritHandle=TRUE;
/* Create the semaphore, with initial value signaled */
_mutex=::CreateSemaphore(&security,1,1,(LPCSTR) NULL);
if (_mutex != (HANDLE) NULL)
return;
throwExceptionExplicit(MagickCore::OptionError,
"mutex initialization failed");
}
#else
// Threads not supported
{
}
#endif
#endif
// Destructor
Magick::MutexLock::~MutexLock(void)
{
#if defined(MAGICKCORE_HAVE_PTHREAD)
(void) ::pthread_mutex_destroy(&_mutex);
#endif
#if defined(_MT) && defined(_VISUALC_)
(void) ::CloseHandle(_mutex);
#endif
}
// Lock mutex
void Magick::MutexLock::lock(void)
{
#if defined(MAGICKCORE_HAVE_PTHREAD)
int
sysError;
if ((sysError=::pthread_mutex_lock(&_mutex)) == 0)
return;
throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed",
strerror(sysError));
#endif
#if defined(_MT) && defined(_VISUALC_)
if (WaitForSingleObject(_mutex,INFINITE) != WAIT_FAILED)
return;
throwExceptionExplicit(MagickCore::OptionError,"mutex lock failed");
#endif
}
// Unlock mutex
void Magick::MutexLock::unlock(void)
{
#if defined(MAGICKCORE_HAVE_PTHREAD)
int
sysError;
if ((sysError=::pthread_mutex_unlock(&_mutex)) == 0)
return;
throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed",
strerror(sysError));
#endif
#if defined(_MT) && defined(_VISUALC_)
if (ReleaseSemaphore(_mutex,1,(LPLONG) NULL) == TRUE)
return;
throwExceptionExplicit(MagickCore::OptionError,"mutex unlock failed");
#endif
}