Odamex
Setting the Standard in Multiplayer Doom
ag-odalaunch/src/oda_thread.h
Go to the documentation of this file.
00001 // Emacs style mode select   -*- C++ -*- 
00002 //-----------------------------------------------------------------------------
00003 //
00004 // $Id: oda_thread.h 2164 2011-05-07 20:10:55Z hypereye $
00005 //
00006 // Copyright (C) 2006-2010 by The Odamex Team.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // DESCRIPTION:
00019 //       AG_Thread C++ Wrapper
00020 //
00021 // AUTHORS:
00022 //       Michael Wood (mwoodj at huntsvegas dot org)
00023 //
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef _ODA_THREAD_H
00027 #define _ODA_THREAD_H
00028 
00029 #ifndef CALL_MEMBER_FN
00030 #define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))
00031 #endif
00032 
00039 namespace agOdalaunch {
00040 
00041 const size_t NUM_THREADS = 5;
00042 
00043 class ODA_ThreadBase {};
00044 
00045 typedef void *(ODA_ThreadBase::*THREAD_FUNC_PTR)(void *);
00046 
00047 typedef struct 
00048 {
00049         ODA_ThreadBase  *classPtr;
00050         THREAD_FUNC_PTR  funcPtr;
00051         AG_Mutex        *rMutex;
00052         bool            *running;
00053         void            *arg;
00054 } ThreadArg_t;
00055 
00056 class ODA_Thread
00057 {
00058 public:
00059         ODA_Thread() { m_Running = false; m_RMutex = NULL; }
00060 
00061         int Create(ODA_ThreadBase *classPtr, THREAD_FUNC_PTR funcPtr, void *arg)
00062         {
00063                 if(m_RMutex)
00064                 {
00065                         if(IsRunning())
00066                                 return -1;
00067                         else
00068                                 AG_ThreadJoin(m_Thread, NULL);
00069                 }
00070                 else
00071                 {
00072                         m_RMutex = new AG_Mutex;
00073                         AG_MutexInit(m_RMutex);
00074                 }
00075 
00076                 ThreadArg_t *targ = new(ThreadArg_t);
00077 
00078                 m_Running = true;
00079 
00080                 targ->classPtr = classPtr;
00081                 targ->funcPtr = funcPtr;
00082                 targ->rMutex = m_RMutex;
00083                 targ->running = &m_Running;
00084                 targ->arg = arg;
00085 
00086                 return AG_ThreadCreate(&m_Thread, CallThreadFunc, targ);
00087         }
00088 
00089         static void *CallThreadFunc(void *arg)
00090         {
00091                 ThreadArg_t *targ = (ThreadArg_t *)arg;
00092 
00093                 if(targ && targ->classPtr && targ->rMutex && targ->running)
00094                 {
00095                         void *ret;
00096 
00097                         ret = CALL_MEMBER_FN(*targ->classPtr, targ->funcPtr)(targ->arg);
00098 
00099                         AG_MutexLock(targ->rMutex);
00100                         *targ->running = false;
00101                         AG_MutexUnlock(targ->rMutex);
00102 
00103                         delete targ;
00104 
00105                         AG_ThreadExit(ret);
00106                 }
00107 
00108                 AG_ThreadExit(NULL);
00109 
00110                 return NULL;
00111         }
00112 
00113         bool IsRunning()
00114         {
00115                 bool val;
00116 
00117                 if(!m_RMutex)
00118                         return false;
00119 
00120                 AG_MutexLock(m_RMutex);
00121                 val = m_Running;
00122                 AG_MutexUnlock(m_RMutex);
00123 
00124                 return val;
00125         }
00126 
00127         void Cancel() { AG_ThreadCancel(m_Thread); }
00128         int Join(void **exitVal) { return AG_ThreadJoin(m_Thread, exitVal); }
00129         int Kill(int signal) { return AG_ThreadKill(m_Thread, signal); }
00130 
00131 private:
00132         AG_Thread  m_Thread;
00133         AG_Mutex  *m_RMutex;
00134         bool       m_Running;
00135 };
00136 
00137 } // namespace
00138 
00139 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends