+++ /dev/null
-/*! ========================================================================
-** Extended Template and Library
-** Thread Abstraction Class Implementation
-** $Id$
-**
-** Copyright (c) 2002 Robert B. Quattlebaum Jr.
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-**
-** === N O T E S ===========================================================
-**
-** This is an internal header file, included by other ETL headers.
-** You should not attempt to use it directly.
-**
-** ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __ETL__THREAD_H_
-#define __ETL__THREAD_H_
-
-/* === H E A D E R S ======================================================= */
-
-#define __USE_GNU
-
-#ifdef HAVE_PTHREAD_H
-# include <pthread.h>
-#endif
-
-#ifdef HAVE_SCHED_H
-# include <sched.h>
-#endif
-
-#ifdef HAVE_CREATETHREAD
-# include <windows.h>
-#endif
-
-/* === M A C R O S ========================================================= */
-
-#if ( defined (HAVE_PTHREAD_CREATE) || defined (HAVE_CLONE) || defined (HAVE_CREATETHREAD) ) && !defined (NO_THREADS)
-# define CALLISTO_THREADS
-#endif
-
-#define THREAD_ENTRYPOINT
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-#if defined(CALLISTO_THREADS) && defined(HAVE_PTHREAD_CREATE)
-static inline void Yield(void)
-{
- sched_yield();
- pthread_testcancel();
-}
-#else
-#ifdef Yield
- #undef Yield
-#endif
-inline void Yield(void) { }
-#endif
-
-#ifdef CALLISTO_THREADS
-
-#ifdef HAVE_PTHREAD_CREATE
-
-class Thread
-{
-public:
- typedef void* entrypoint_return;
-private:
-
- pthread_t thread;
- int *references;
- entrypoint_return (*entrypoint)(void *);
- void *context;
-public:
- Thread(void *(*ep)(void *)=NULL,void *context=NULL):
- references(NULL),entrypoint(ep),context(context) { }
- Thread(const Thread &t)
- {
- thread=t.thread;
- references=t.references;
- entrypoint=t.entrypoint;
- context=t.context;
- if(references)
- (*references)++;
- }
- const Thread &operator=(const Thread &rhs)
- {
- if(references)
- {
- (*references)--;
- if(*references==0)
- stop();
- }
- thread=rhs.thread;
- references=rhs.references;
- entrypoint=rhs.entrypoint;
- context=rhs.context;
- if(references)
- (*references)++;
- return *this;
- }
-
- void start(void)
- {
- references = new int;
- *references = 1;
- pthread_create(&thread,NULL,entrypoint,context);
-// pthread_detach(thread);
- }
-
- void stop(void)
- {
- delete references;
- references=NULL;
- void *exit_status;
- pthread_cancel(thread);
- pthread_join(thread,&exit_status);
- }
-
- static void TestStop()
- {
- pthread_testcancel();
- }
-
- static void SyncStop()
- {
- int i;
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&i);
- }
-
- static void AsyncStop()
- {
- int i;
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&i);
- }
-
- ~Thread()
- {
- if(references)
- {
- (*references)--;
- if(*references==0)
- stop();
- }
- }
-};
-
-class Mutex
-{
- pthread_mutex_t mutex;
- pthread_t locker;
- int depth;
-public:
-
- Mutex()
- {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- //#ifdef PTHREAD_PRIO_INHERIT
- //pthread_mutexattr_setprioceiling(&attr,PTHREAD_PRIO_INHERIT);
- //#endif
- #ifdef PTHREAD_MUTEX_RECURSIVE
- pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
- #endif
- pthread_mutex_init(&mutex,&attr);
- pthread_mutexattr_destroy(&attr);
- locker=0;
- depth=0;
- }
-
- ~Mutex()
- { pthread_mutex_destroy(&mutex); }
-
- void Lock(void)
- {
- if(!locker || locker!=pthread_self())
- {
- pthread_mutex_lock(&mutex);
- locker=pthread_self();
- depth=0;
- return;
- }
- depth++;
- }
-
- bool TryLock(void)
- { return !(bool) pthread_mutex_trylock(&mutex); }
-
- void UnLock(void)
- {
- if(depth)
- {
- depth--;
- return;
- }
- pthread_mutex_unlock(&mutex);
- locker=0;
- }
-};
-
-#ifdef HAVE_PTHREAD_RW_LOCK_INIT
-class ReadWriteLock
-{
- pthread_rwlock_t rwlock;
-public:
-
- ReadWriteLock()
- { pthread_rwlock_init(&rwlock,NULL); }
-
- ~ReadWriteLock()
- { pthread_rwlock_destroy(&rwlock); }
-
- void LockRead(void)
- { pthread_rwlock_rdlock(&rwlock); }
-
- void LockWrite(void)
- { pthread_rwlock_wrlock(&rwlock); }
-
- bool TryLockRead(void)
- { return !(bool)pthread_rwlock_tryrdlock(&rwlock); }
-
- bool TryLockWrite(void)
- { return !(bool)pthread_rwlock_trywrlock(&rwlock); }
-
- void UnLockWrite(void)
- { pthread_rwlock_unlock(&rwlock); }
-
- void UnLockRead(void)
- { pthread_rwlock_unlock(&rwlock); }
-};
-#else
-//*
-class ReadWriteLock : public Mutex
-{
-public:
-
- ReadWriteLock()
- { }
-
- ~ReadWriteLock()
- { }
-
- void LockRead(void)
- { Lock(); }
-
- void LockWrite(void)
- { Lock(); }
-
- bool TryLockRead(void)
- { return TryLock(); }
-
- bool TryLockWrite(void)
- { return TryLock(); }
-
- void UnLockWrite(void)
- { UnLock(); }
-
- void UnLockRead(void)
- { UnLock(); }
-};
-#endif
-
-/*
-class Condition
-{
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-public:
- Condition()
- { pthread_cond_init(&cond,NULL); pthread_mutex_init(&mutex,NULL); }
- ~Condition()
- { pthread_cond_destroy(&cond); pthread_mutex_destroy(&mutex);}
- void operator()(void)
- { pthread_cond_signal(&cond); }
- void Wait(void)
- {
- pthread_mutex_lock(&mutex);
- pthread_cond_wait(&cond,&mutex);
- pthread_mutex_unlock(&mutex);
- }
-};
-*/
-
-#else // if defined HAVE_PTHREAD
-#ifdef HAVE_CREATETHREAD
-
-
-#ifdef THREAD_ENTRYPOINT
-#undef THREAD_ENTRYPOINT
-#endif
-#define THREAD_ENTRYPOINT __stdcall
-class Thread
-{
-public:
- typedef unsigned long entrypoint_return;
-private:
-
- unsigned long thread;
- HANDLE handle;
- int *references;
-
- entrypoint_return (THREAD_ENTRYPOINT *entrypoint)(void *);
-
- void *context;
-
- HDC hdc;
- HGLRC hglrc;
-
- static entrypoint_return THREAD_ENTRYPOINT thread_prefix(void*data)
- {
- Thread *thread=(Thread *)data;
-
- if(thread->hglrc)
- wglMakeCurrent(thread->hdc, thread->hglrc);
-
- return thread->entrypoint(thread->context);
- }
-
-public:
- Thread(entrypoint_return (THREAD_ENTRYPOINT *ep)(void *)=NULL,void *context=NULL):
- references(NULL),entrypoint(ep),context(context) { }
- Thread(const Thread &t)
- {
- thread=t.thread;
- handle=t.handle;
- references=t.references;
- entrypoint=t.entrypoint;
- context=t.context;
- handle=NULL;
- if(references)
- (*references)++;
- }
- const Thread &operator=(const Thread &rhs)
- {
- if(references)
- {
- (*references)--;
- if(*references==0)
- stop();
- }
- thread=rhs.thread;
- handle=rhs.handle;
- references=rhs.references;
- entrypoint=rhs.entrypoint;
- context=rhs.context;
- if(references)
- (*references)++;
- return *this;
- }
-
- void start(void)
- {
- references = new int;
- *references = 1;
-
- hglrc=wglGetCurrentContext();
- hdc=wglGetCurrentDC();
-
- handle=CreateThread(
- NULL, // Security stuff
- 0, // STACK
- thread_prefix, // thread function
- (void*)this, // thread argument
- 0, // creation option
- &thread // thread identifier
- );
- }
-
- void stop(void)
- {
- delete references;
- references=NULL;
-
- TerminateThread(handle, FALSE);
- }
-
- int wait(void)
- {
- if(handle)
- {
- WaitForSingleObject(handle, INFINITE);
- CloseHandle(handle);
- }
- return 0;
- }
-
- static void TestStop()
- {
- }
-
- static void SyncStop()
- {
- }
-
- static void AsyncStop()
- {
- }
-
- ~Thread()
- {
- if(references)
- {
- (*references)--;
- if(*references==0)
- stop();
- }
- }
-};
-
-class Mutex
-{
- HANDLE handle;
-public:
-
- Mutex()
- {
- handle = CreateMutex(NULL, FALSE, NULL);
- }
-
- ~Mutex()
- {
- CloseHandle(handle);
- }
-
- void Lock(void)
- {
- WaitForSingleObject(handle, INFINITE);
- }
-
- bool TryLock(void)
- {
- return WaitForSingleObject(handle, INFINITE)==WAIT_FAILED;
- }
-
- void UnLock(void)
- {
- ReleaseMutex(handle);
- }
-};
-
-
-#endif // if defined HAVE_CREATETHREAD
-#endif // if defined HAVE_PTHREAD_CREATE
-#endif // if defined CALLISTO_THREADS
-
-
-#if !defined(CALLISTO_THREADS)
-// Dummy object used when not threading
-class ReadWriteLock
-{
-public:
-
- ReadWriteLock() {}
- ~ReadWriteLock() {}
- void LockRead(void) {}
- void LockWrite(void) {}
- bool TryLockRead(void) {return true;}
- bool TryLockWrite(void) {return true;}
- void UnLockRead(void) {}
- void UnLockWrite(void) {}
-};
-
-class Mutex
-{
-public:
-
- Mutex(){}
- ~Mutex(){}
- void Lock(void){}
- bool TryLock(void){return true;}
- void UnLock(void){}
-};
-
-#endif
-
-class Condition : private Mutex
-{
- bool flag;
-public:
- Condition()
- { flag=false; }
- ~Condition()
- { }
- void operator()(void)
- { flag=true; }
- void Wait(void)
- {
- Lock();
- while(!flag)Yield();
- flag=false;
- UnLock();
- }
- void WaitNext(void)
- {
- Lock();
- flag=false;
- while(!flag)Yield();
- UnLock();
- }
-};
-
-/* === E X T E R N S ======================================================= */
-
-/* === E N D =============================================================== */
-
-#endif