/*------------------------------------------------------------------------------ * 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(_CLCOMPILER_MSVC) || defined(__MINGW32__) #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 //todo: add back CND_PRECONDITION(c==0,m) #define _CLPTHREAD_CHECK(c,m) c; //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