blob: 7d5907716003c3462c748567f35527d9759d8778 [file] [log] [blame]
/*------------------------------------------------------------------------------
* 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