Update of /cvsroot/planeshift/planeshift/src/common/util In directory usw-pr-cvs1:/tmp/cvs-serv2992/src/common/util Modified Files: Makefile.am binarytree.cpp binarytree.h gameevent.cpp genqueue.cpp genqueue.h psxmlparser.cpp Added Files: condition.h mutex.h posixcondition.h posixmutex.h posixthread.h posixthread.inc sleep.h thread.cpp thread.h wincondition.h winmutex.h winthread.h winthread.inc Log Message: -Get rid of the old clumsy sal code -Implemented some own classes for threading, mutexes and conditions -pthread implementation is ok, msvc is done blindly and misses a correct condition implementation but I don't want to keep the changes back any longer... --- NEW FILE: condition.h --- #ifndef __CONDITION_H__ #define __CONDITION_H__ #ifdef HAVE_PTH # include "posixcondition.h" #else # ifdef USE_WINTASK # include "wincondition.h" # endif #endif class Condition : public ConditionInternals { public: Condition () {} ~Condition () {} void NotifyOne () { ConditionInternals::NotifyOne (); } void NotifyAll () { ConditionInternals::NotifyAll (); } void Wait () { ConditionInternals::Wait (); } private: Condition (const Condition&) : ConditionInternals () { } }; #endif --- NEW FILE: mutex.h --- #ifndef __MUTEX_H__ #define __MUTEX_H__ #ifdef HAVE_PTH #include "util/posixmutex.h" #elif USE_WINTASK #include "util/winmutex.h" #endif /** This class represents a Mutex. A mutex has 2 possible states: unlocked and * locked. A thread can lock the mutex (also recursively ie 1 thread can lock * the mutex several times, but needs to unlock it several times then). While * a mutex is locked no other thread can lock the mutex. A call to Lock blocks * and waits till the mutex is free again. * * This Mutex implementation works with scope. you aren't allowed to access * the mutex directly but should use the MutexLock class for locking the mutex */ class Mutex : public MutexInternals { public: Mutex () : MutexInternals() {} protected: friend class MutexLock; void MutexLock () { _Lock (); } void MutexUnlock () { _Unlock (); } private: // COPY contructor is forbidden Mutex (const Mutex&) : MutexInternals() { } }; /** This is a utility class for locking a Mutex. If A MutexLock class is * created it locks the mutex, when it is destroyed it unlocks the Mutex * again. So locking a mutex can happen by creating a MutexLock object on the * stack. The compiler will then take care that the Unlock calls will be done * in each case. * Example: * void Myfunc() { * MutexLock (mymutex); * do something special * * return; * } */ class MutexLock { public: MutexLock (Mutex& newmutex) : mutex(newmutex) { mutex.MutexLock(); } ~MutexLock () { mutex.MutexUnlock(); } private: Mutex& mutex; }; #endif --- NEW FILE: posixcondition.h --- #ifndef __POSIXCONDITION_H__ #define __POSIXCONDITION_H__ #include <pthread.h> #include <assert.h> class ConditionInternals { public: ConditionInternals () { assert (pthread_mutex_init (&mutex, NULL) >= 0); assert (pthread_cond_init (&cond, NULL) >= 0); } ~ConditionInternals () { pthread_cond_destroy (&cond); pthread_mutex_destroy (&mutex); } protected: void NotifyOne () { pthread_cond_signal (&cond); } void NotifyAll () { pthread_cond_broadcast (&cond); } void Wait () { pthread_mutex_lock (&mutex); pthread_cond_wait (&cond, &mutex); } pthread_cond_t cond; pthread_mutex_t mutex; }; #endif --- NEW FILE: posixmutex.h --- #ifndef __POSIXMUTEX_H__ #define __POSIXMUTEX_H__ #include <pthread.h> class MutexInternals { public: MutexInternals () { pthread_mutexattr_t mutexattr; pthread_mutexattr_init (&mutexattr); assert (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP) >= 0); assert (pthread_mutex_init (&_mutex, &mutexattr) >= 0); } ~MutexInternals () { pthread_mutex_destroy (&_mutex); } protected: void _Lock () { pthread_mutex_lock (&_mutex); } void _Unlock () { pthread_mutex_unlock (&_mutex); } protected: pthread_mutex_t _mutex; }; #endif --- NEW FILE: posixthread.h --- #ifndef __PSPTHREAD_H__ #define __PSPTHREAD_H__ #ifdef __FreeBSD__ #include <sched.h> #endif #include <pthread.h> class ThreadInternals { public: ThreadInternals (); protected: bool running; pthread_t thread; pthread_attr_t thread_attr; static void* PThreadMain(void* arg); }; #endif --- NEW FILE: posixthread.inc --- #include <assert.h> #include <unistd.h> #include "util/sleep.h" #include "util/thread.h" ThreadInternals::ThreadInternals () : running (false) { } Thread::Thread () { } Thread::~Thread () { assert (StopThread ()); } bool Thread::StartThread () { if (running) return true; pthread_attr_init (&thread_attr); if (pthread_create (&thread, &thread_attr, PThreadMain, this) != 0) return false; running = true; return true; } bool Thread::StopThread () { if (!running) return true; if (pthread_cancel (thread) < 0) return false; running = false; return true; } void* ThreadInternals::PThreadMain (void* arg) { Thread* thread = (Thread*) arg; assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0) >= 0); assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0) >= 0); assert (pthread_detach(thread->thread) >= 0); thread->ThreadMain (); return NULL; } //--------------------------------------------------------------------------- void psSleep(unsigned long msec) { usleep (msec * 1000); } --- NEW FILE: sleep.h --- #ifndef __PSSLEEP_H__ #define __PSSLEEP_H__ void psSleep (unsigned long msec); #endif --- NEW FILE: thread.cpp --- #include <config.h> #ifdef HAVE_PTH # include "posixthread.inc" #else # ifdef USE_WINTASK # include "winthread.inc" # endif #endif --- NEW FILE: thread.h --- #ifndef __PSTHREAD_H__ #define __PSTHREAD_H__ #if defined(HAVE_PTH) #include "util/posixthread.h" #endif #if defined(USE_WINTASK) #include "util/winthread.h" #endif class Thread : public ThreadInternals { public: Thread (); virtual ~Thread (); bool StartThread (); bool StopThread (); virtual void ThreadMain () = 0; }; #endif --- NEW FILE: wincondition.h --- #ifndef __WINCONDITION_H__ #define __WINCONDITION_H__ #include <windows.h> #include "util/sleep.h" // XXX XXX XXX Implement this with a correct threading version and not this // crap ;-) class ConditionInternals { public: ConditionInternals () : signaled (false) { } ~ConditionInternals () { } protected: void NotifyOne () { signaled = true; } void NotifyAll () { signaled = true; } void Wait () { while (!signaled) psSleep (50); signaled = false; } protected: bool signaled; }; #endif --- NEW FILE: winmutex.h --- #ifndef __WINMUTEX_H__ #define __WINMUTEX_H__ #include <windows.h> class MutexInternals { public: MutexInternals () { InitializeCriticalSection (&_cs); } ~MutexInternals () { DeleteCriticalSection (&_cs); } protected: void _Lock () { EnterCriticalSection (&_cs); } void _Unlock () { LeaveCriticalSection (&_cs); } CRITICAL_SECTION _cs; }; #endif --- NEW FILE: winthread.h --- #ifndef __WINDTHREAD_H__ #define __WINDTHREAD_H__ #include <windows.h> class ThreadInternals { public: DWORD threadid; HANDLE threadhandle; protected: static void WINAPI WinThreadMain(void* arg); }; #endif --- NEW FILE: winthread.inc --- #include <assert.h> #include "util/thread.h" Thread::Thread () { threadhandle = 0; threadid = 0; } Thread::~Thread () { assert (StopThread ()); } bool Thread::StartThread () { if (threadhandle) return false; threadhandle = CreateThread (NULL, 64*1024, LPTHREAD_START_ROUTINE(WinThreadMain), this, CREATE_SUSPENDED, &threadid); ResumeThread (threadhandle); } bool Thread::StopThread () { if (!threadhandle) return false; TerminateThread (threadhandle, 0); CloseHandle (threadhandle); threadhandle = 0; threadid = 0; return true; } //--------------------------------------------------------------------------- void psSleep(unsigned long msec) { Sleep(msec); } Index: Makefile.am =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/Makefile.am,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Makefile.am 30 Jun 2002 11:33:23 -0000 1.9 --- Makefile.am 1 Jul 2002 02:49:27 -0000 1.10 *************** *** 9,13 **** libpsutil_la_SOURCES = binarytree.cpp genqueue.cpp refcount.cpp pserror.cpp \ xmlstring.cpp psxmlparser.cpp strutil.cpp psres.cpp \ ! psresmngr.cpp delimitedstring.cpp gameevent.cpp \ $(PSUTILHEADERS) --- 9,13 ---- libpsutil_la_SOURCES = binarytree.cpp genqueue.cpp refcount.cpp pserror.cpp \ xmlstring.cpp psxmlparser.cpp strutil.cpp psres.cpp \ ! psresmngr.cpp delimitedstring.cpp thread.cpp gameevent.cpp \ $(PSUTILHEADERS) Index: binarytree.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/binarytree.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** binarytree.cpp 5 May 2002 13:04:41 -0000 1.10 --- binarytree.cpp 1 Jul 2002 02:49:27 -0000 1.11 *************** *** 386,393 **** while (pNodeList[iDepth]->pLeft) ! { pNodeList[iDepth+1] = pNodeList[iDepth]->pLeft; ! iDepth++; ! } lIndex = 0; return pNodeList[iDepth]->pObj; --- 386,393 ---- while (pNodeList[iDepth]->pLeft) ! { pNodeList[iDepth+1] = pNodeList[iDepth]->pLeft; ! iDepth++; ! } lIndex = 0; return pNodeList[iDepth]->pObj; Index: binarytree.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/binarytree.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** binarytree.h 5 May 2002 13:04:41 -0000 1.6 --- binarytree.h 1 Jul 2002 02:49:27 -0000 1.7 *************** *** 32,49 **** friend class BinaryTreeIterator<T>; ! BinaryTree(); ! ~BinaryTree(); ! ! long Count(void) const { return lCount; }; ! // Node operations ! BinaryTreeNode<T> *Add(T *pT,int owner = false); ! int Delete(T *pT); ! ! T *Find(T *pT) const; ! T *FindPartial(T *pPartialT,int bGuaranteeUnique=1) const; ! ! const BinaryTreeNode<T> *GetNodeRef(T *pT) const; ! void Clear(void); }; --- 32,49 ---- friend class BinaryTreeIterator<T>; ! BinaryTree(); ! ~BinaryTree(); ! long Count(void) const { return lCount; }; ! // Node operations ! BinaryTreeNode<T> *Add(T *pT,int owner = false); ! int Delete(T *pT); ! ! T *Find(T *pT) const; ! T *FindPartial(T *pPartialT,int bGuaranteeUnique=1) const; ! ! const BinaryTreeNode<T> *GetNodeRef(T *pT) const; ! ! void Clear(void); }; *************** *** 51,64 **** { protected: ! T *pObj; ! int iRefCount; ! bool bOwner; ! BinaryTreeNode<T> *pLeft; ! BinaryTreeNode<T> *pRight; public: friend class BinaryTree<T>; friend class BinaryTreeIterator<T>; ! BinaryTreeNode(T *pT, bool bOwner); ~BinaryTreeNode(); --- 51,64 ---- { protected: ! T *pObj; ! int iRefCount; ! bool bOwner; ! BinaryTreeNode<T> *pLeft; ! BinaryTreeNode<T> *pRight; public: friend class BinaryTree<T>; friend class BinaryTreeIterator<T>; ! BinaryTreeNode(T *pT, bool bOwner); ~BinaryTreeNode(); Index: gameevent.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/gameevent.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** gameevent.cpp 30 Jun 2002 11:33:49 -0000 1.1 --- gameevent.cpp 1 Jul 2002 02:49:27 -0000 1.2 *************** *** 17,28 **** * */ - #include <config.h> #include "util/gameevent.h" - int psGameEvent::nextid; /// id counter sequence number - psGameEvent::psGameEvent(int ticks) --- 17,25 ---- Index: genqueue.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/genqueue.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** genqueue.cpp 21 Apr 2002 13:42:54 -0000 1.9 --- genqueue.cpp 1 Jul 2002 02:49:27 -0000 1.10 *************** *** 52,73 **** unsigned int tqend; ! qlock.enter(); tqend = (qend + 1) % qsize; // check if queue is full if (tqend == qstart) - { - qlock.leave(); return false; - } // add Message to queue qbuffer[qend]=msg; qend=tqend; - qlock.leave(); ! if (waiting) { ! waitsem.signal(); ! waiting=false; ! } return true; --- 52,66 ---- unsigned int tqend; ! MutexLock lock(mutex); tqend = (qend + 1) % qsize; // check if queue is full if (tqend == qstart) return false; // add Message to queue qbuffer[qend]=msg; qend=tqend; ! datacondition.NotifyOne (); return true; *************** *** 77,92 **** queuetyp* GenericQueue<queuetyp>::Get () { ! qlock.enter(); // check if queue is empty if (IsEmpty()) - { - qlock.leave(); return 0; - } // removes Message from queue queuetyp* ptr = *(qbuffer + qstart); qstart = (qstart + 1) % qsize; - qlock.leave(); return ptr; --- 70,82 ---- queuetyp* GenericQueue<queuetyp>::Get () { ! MutexLock lock(mutex); ! // check if queue is empty if (IsEmpty()) return 0; // removes Message from queue queuetyp* ptr = *(qbuffer + qstart); qstart = (qstart + 1) % qsize; return ptr; *************** *** 96,110 **** queuetyp* GenericQueue<queuetyp>::Peek() { ! qlock.enter(); // check if queue is empty if (IsEmpty()) - { - qlock.leave(); return 0; - } // does NOT remove Message from queue queuetyp* ptr = *(qbuffer + qstart); - qlock.leave(); return ptr; --- 86,97 ---- queuetyp* GenericQueue<queuetyp>::Peek() { ! MutexLock lock(mutex); ! // check if queue is empty if (IsEmpty()) return 0; // does NOT remove Message from queue queuetyp* ptr = *(qbuffer + qstart); return ptr; *************** *** 119,125 **** return temp; ! // if there was no message wait till 1 is there ! waiting=true; ! waitsem.wait(); return Get(); --- 106,110 ---- return temp; ! datacondition.Wait (); return Get(); Index: genqueue.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/genqueue.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** genqueue.h 29 Apr 2002 15:43:45 -0000 1.6 --- genqueue.h 1 Jul 2002 02:49:27 -0000 1.7 *************** *** 25,29 **** #define __GENQUEUE_H__ ! #include "sal/task.h" /** --- 25,30 ---- #define __GENQUEUE_H__ ! #include "util/mutex.h" ! #include "util/condition.h" /** *************** *** 67,76 **** return ((qend + 1) % size) == qstart; } protected: queuetyp **qbuffer; unsigned int qstart, qend; unsigned int qsize; ! mutex qlock; ! semaphore waitsem; bool waiting; }; --- 68,78 ---- return ((qend + 1) % size) == qstart; } + protected: queuetyp **qbuffer; unsigned int qstart, qend; unsigned int qsize; ! Mutex mutex; ! Condition datacondition; bool waiting; }; Index: psxmlparser.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/common/util/psxmlparser.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** psxmlparser.cpp 30 May 2002 05:52:56 -0000 1.12 --- psxmlparser.cpp 1 Jul 2002 02:49:27 -0000 1.13 *************** *** 144,148 **** { start++; ! if (start >= Length()) return; } --- 144,148 ---- { start++; ! if (start >= (int) Length()) return; } *************** *** 151,155 **** start++; // skip = sign ! if (start >= Length()) return; --- 151,155 ---- start++; // skip = sign ! if (start >= (int) Length()) return; *************** *** 158,162 **** { start++; ! if (start >= Length()) return; } --- 158,162 ---- { start++; ! if (start >= (int) Length()) return; } |