1
/*------------------------------------------------------------------------------
2
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
4
* Distributable under the terms of either the Apache License (Version 2.0) or
5
* the GNU Lesser General Public License, as specified in the COPYING file.
6
------------------------------------------------------------------------------*/
7
#include "CLucene/_SharedHeader.h"
8
#include "CLucene/LuceneThreads.h"
14
#ifndef _CL_DISABLE_MULTITHREADING
16
#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX)
18
#if defined(_LUCENE_PRAGMA_WARNINGS)
19
#pragma message ("==================Not implementing any thread mutex==================")
21
#warning "==================Not implementing any thread mutex=================="
26
#elif defined(_CL_HAVE_WIN32_THREADS)
27
struct mutex_thread::Internal{
31
mutex_thread::mutex_thread(const mutex_thread& clone):
32
_internal(new Internal)
34
InitializeCriticalSection(&_internal->mtx);
36
mutex_thread::mutex_thread():
37
_internal(new Internal)
39
InitializeCriticalSection(&_internal->mtx);
42
mutex_thread::~mutex_thread()
44
DeleteCriticalSection(&_internal->mtx);
48
void mutex_thread::lock()
50
EnterCriticalSection(&_internal->mtx);
53
void mutex_thread::unlock()
55
LeaveCriticalSection(&_internal->mtx);
58
_LUCENE_THREADID_TYPE mutex_thread::_GetCurrentThreadId(){
59
return GetCurrentThreadId();
61
void mutex_thread::_exitThread(int val){
65
int32_t mutex_thread::atomic_increment(_LUCENE_ATOMIC_INT *theInteger){
67
return _InterlockedIncrement64(theInteger);
69
return InterlockedIncrement(theInteger);
72
int32_t mutex_thread::atomic_decrement(_LUCENE_ATOMIC_INT *theInteger){
74
return _InterlockedDecrement64(theInteger);
76
return InterlockedDecrement(theInteger);
82
class shared_condition::Internal{
86
_event = CreateEventA( NULL, false, false, NULL );
89
CloseHandle( _event );
92
shared_condition::shared_condition(){
93
_internal = new Internal;
95
shared_condition::~shared_condition(){
98
void shared_condition::Wait(mutex_thread* shared_lock){
99
shared_lock->unlock();
100
_cl_dword_t dwRes = WaitForSingleObject( _internal->_event, 0xFFFFFFFF );
101
assert ( 0x0 == dwRes );
104
void shared_condition::NotifyAll(){
105
bool bRes = SetEvent(_internal->_event);
109
_LUCENE_THREADID_TYPE mutex_thread::CreateThread(luceneThreadStartRoutine* func, void* arg){
110
return (_LUCENE_THREADID_TYPE) ::_beginthread (func, 0, arg);
112
void mutex_thread::JoinThread(_LUCENE_THREADID_TYPE id){
113
WaitForSingleObject((void*)id, 0xFFFFFFFF);
117
#elif defined(_CL_HAVE_PTHREAD)
119
#error ACK! You need to compile with _REENTRANT defined since this uses threads
122
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
123
bool mutex_pthread_attr_initd=false;
124
pthread_mutexattr_t mutex_thread_attr;
127
#ifdef _CL__CND_DEBUG
128
#define _CLPTHREAD_CHECK(c,m) CND_PRECONDITION(c==0,m)
130
#define _CLPTHREAD_CHECK(c,m) c;
133
struct mutex_thread::Internal{
135
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
137
unsigned int lockCount;
141
mutex_thread::mutex_thread(const mutex_thread& /*clone*/):
142
_internal(new Internal)
144
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
145
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, &mutex_thread_attr), "mutex_thread(clone) constructor failed")
147
#if defined(__hpux) && defined(_DECTHREADS_)
148
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, pthread_mutexattr_default), "mutex_thread(clone) constructor failed")
150
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, 0), "mutex_thread(clone) constructor failed")
152
_internal->lockCount=0;
153
_internal->lockOwner=0;
156
mutex_thread::mutex_thread():
157
_internal(new Internal)
159
#ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
160
if ( mutex_pthread_attr_initd == false ){
161
pthread_mutexattr_init(&mutex_thread_attr);
162
pthread_mutexattr_settype(&mutex_thread_attr, PTHREAD_MUTEX_RECURSIVE);
163
mutex_pthread_attr_initd = true;
165
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, &mutex_thread_attr), "mutex_thread(clone) constructor failed")
167
#if defined(__hpux) && defined(_DECTHREADS_)
168
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, pthread_mutexattr_default), "mutex_thread(clone) constructor failed")
170
_CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, 0), "mutex_thread(clone) constructor failed")
172
_internal->lockCount=0;
173
_internal->lockOwner=0;
177
mutex_thread::~mutex_thread()
179
_CLPTHREAD_CHECK(pthread_mutex_destroy(&_internal->mtx), "~mutex_thread destructor failed")
183
_LUCENE_THREADID_TYPE mutex_thread::_GetCurrentThreadId(){
184
return pthread_self();
187
int32_t atomic_threads::atomic_increment(_LUCENE_ATOMIC_INT *theInteger){
188
#ifdef _CL_HAVE_GCC_ATOMIC_FUNCTIONS
189
return __sync_add_and_fetch(theInteger, 1);
191
SCOPED_LOCK_MUTEX(theInteger->THIS_LOCK)
192
return ++theInteger->value;
195
int32_t atomic_threads::atomic_decrement(_LUCENE_ATOMIC_INT *theInteger){
196
#ifdef _CL_HAVE_GCC_ATOMIC_FUNCTIONS
197
return __sync_sub_and_fetch(theInteger, 1);
199
SCOPED_LOCK_MUTEX(theInteger->THIS_LOCK)
200
return --theInteger->value;
205
_LUCENE_THREADID_TYPE mutex_thread::CreateThread(luceneThreadStartRoutine* func, void* arg){
206
_LUCENE_THREADID_TYPE ret;
207
int nRes = pthread_create(&ret, NULL, func, arg);
211
void mutex_thread::JoinThread(_LUCENE_THREADID_TYPE id){
212
pthread_join(id, NULL);
215
void mutex_thread::lock()
217
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
218
pthread_t currentThread = pthread_self();
219
if( pthread_equal( _internal->lockOwner, currentThread ) ) {
220
++_internal->lockCount;
222
_CLPTHREAD_CHECK(pthread_mutex_lock(&_internal->mtx), "mutex_thread::lock")
223
_internal->lockOwner = currentThread;
224
_internal->lockCount = 1;
227
_CLPTHREAD_CHECK(pthread_mutex_lock(&_internal->mtx), "mutex_thread::lock")
231
void mutex_thread::unlock()
233
#ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE
234
--_internal->lockCount;
235
if( _internal->lockCount == 0 )
237
_internal->lockOwner = 0;
238
_CLPTHREAD_CHECK(pthread_mutex_unlock(&_internal->mtx), "mutex_thread::unlock")
241
_CLPTHREAD_CHECK(pthread_mutex_unlock(&_internal->mtx), "mutex_thread::unlock")
246
struct shared_condition::Internal{
247
pthread_cond_t condition;
249
pthread_cond_init (&condition, NULL);
252
pthread_cond_destroy(&condition);
255
shared_condition::shared_condition(){
256
_internal = new Internal;
258
shared_condition::~shared_condition(){
261
void shared_condition::Wait(mutex_thread* shared_lock){
263
res = pthread_cond_wait(&_internal->condition, &shared_lock->_internal->mtx);
266
void shared_condition::NotifyAll(){
268
res = pthread_cond_broadcast(&_internal->condition);
273
#endif //thread impl choice
276
mutexGuard::mutexGuard(const mutexGuard& /*clone*/){
280
mutexGuard::mutexGuard( _LUCENE_THREADMUTEX& rMutex ) :
285
mutexGuard::~mutexGuard()
290
#endif //!_CL_DISABLE_MULTITHREADING