/*------------------------------------------------------------------------------ | |
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team | |
* | |
* Distributable under the terms of either the Apache License (Version 2.0) or | |
* the GNU Lesser General Public License, as specified in the COPYING file. | |
------------------------------------------------------------------------------*/ | |
#include "CLucene/StdHeader.h" | |
#ifndef _CL_DISABLE_MULTITHREADING | |
CL_NS_DEF(util) | |
mutexGuard::mutexGuard(const mutexGuard& clone){ | |
//no autoclone | |
mrMutex = NULL; | |
} | |
mutexGuard::mutexGuard( _LUCENE_THREADMUTEX& rMutex ) : | |
mrMutex(&rMutex) | |
{ | |
mrMutex->lock(); | |
} | |
mutexGuard::~mutexGuard() | |
{ | |
mrMutex->unlock(); | |
} | |
#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX) | |
//do nothing | |
#if defined(_LUCENE_PRAGMA_WARNINGS) | |
#pragma message ("==================Not implementing any thread mutex==================") | |
#else | |
#warning "==================Not implementing any thread mutex==================" | |
#endif | |
#elif defined(_CL_HAVE_WIN32_THREADS) | |
#include "CLucene/config/threadCSection.h" | |
#if !defined(LUCENE_USE_WINDOWS_H) && !defined(_WINDOWS_) | |
//we have not explicity included windows.h and windows.h has | |
//not been included (check _WINDOWS_), then we must define | |
//our own definitions to the thread locking functions: | |
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *); | |
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *); | |
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *); | |
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *); | |
extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); | |
#endif | |
mutex_win32::mutex_win32(const mutex_win32& clone){ | |
InitializeCriticalSection(&mtx); | |
} | |
mutex_win32::mutex_win32() | |
{ | |
InitializeCriticalSection(&mtx); | |
} | |
mutex_win32::~mutex_win32() | |
{ | |
DeleteCriticalSection(&mtx); | |
} | |
void mutex_win32::lock() | |
{ | |
EnterCriticalSection(&mtx); | |
} | |
void mutex_win32::unlock() | |
{ | |
LeaveCriticalSection(&mtx); | |
} | |
#elif defined(_CL_HAVE_PTHREAD) | |
#include "CLucene/config/threadPthread.h" | |
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE | |
bool mutex_pthread_attr_initd=false; | |
pthread_mutexattr_t mutex_pthread_attr; | |
#endif | |
#ifdef _CL__CND_DEBUG | |
#define _CLPTHREAD_CHECK(c,m) CND_PRECONDITION(c==0,m) | |
#else | |
#define _CLPTHREAD_CHECK(c,m) c; | |
#endif | |
mutex_pthread::mutex_pthread(const mutex_pthread& clone){ | |
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed") | |
#else | |
#if defined(__hpux) && defined(_DECTHREADS_) | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed") | |
#else | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed") | |
#endif | |
lockCount=0; | |
lockOwner=0; | |
#endif | |
} | |
mutex_pthread::mutex_pthread() | |
{ | |
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE | |
if ( mutex_pthread_attr_initd == false ){ | |
pthread_mutexattr_init(&mutex_pthread_attr); | |
pthread_mutexattr_settype(&mutex_pthread_attr, PTHREAD_MUTEX_RECURSIVE); | |
mutex_pthread_attr_initd = true; | |
} | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, &mutex_pthread_attr), "mutex_pthread(clone) constructor failed") | |
#else | |
#if defined(__hpux) && defined(_DECTHREADS_) | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, pthread_mutexattr_default), "mutex_pthread(clone) constructor failed") | |
#else | |
_CLPTHREAD_CHECK(pthread_mutex_init(&mtx, 0), "mutex_pthread(clone) constructor failed") | |
#endif | |
lockCount=0; | |
lockOwner=0; | |
#endif | |
} | |
mutex_pthread::~mutex_pthread() | |
{ | |
_CLPTHREAD_CHECK(pthread_mutex_destroy(&mtx), "~mutex_pthread destructor failed") | |
} | |
void mutex_pthread::lock() | |
{ | |
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE | |
pthread_t currentThread = pthread_self(); | |
if( pthread_equal( lockOwner, currentThread ) ) { | |
++lockCount; | |
} else { | |
_CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock") | |
lockOwner = currentThread; | |
lockCount = 1; | |
} | |
#else | |
_CLPTHREAD_CHECK(pthread_mutex_lock(&mtx), "mutex_pthread::lock") | |
#endif | |
} | |
void mutex_pthread::unlock() | |
{ | |
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE | |
--lockCount; | |
if( lockCount == 0 ) | |
{ | |
lockOwner = 0; | |
_CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock") | |
} | |
#else | |
_CLPTHREAD_CHECK(pthread_mutex_unlock(&mtx), "mutex_pthread::unlock") | |
#endif | |
} | |
#endif //thread impl choice | |
CL_NS_END | |
#endif //!_CL_DISABLE_MULTITHREADING |