NptThreads.h

00001 /*****************************************************************
00002 |
00003 |   Neptune - Threads
00004 |
00005 |   (c) 2001-2006 Gilles Boccon-Gibod
00006 |   Author: Gilles Boccon-Gibod (bok@bok.net)
00007 |
00008  ****************************************************************/
00009 
00010 #ifndef _NPT_THREADS_H_
00011 #define _NPT_THREADS_H_
00012 
00013 /*----------------------------------------------------------------------
00014 |   includes
00015 +---------------------------------------------------------------------*/
00016 #include "NptTypes.h"
00017 #include "NptConstants.h"
00018 #include "NptInterfaces.h"
00019 
00020 /*----------------------------------------------------------------------
00021 |   error codes
00022 +---------------------------------------------------------------------*/
00023 const int NPT_ERROR_CALLBACK_HANDLER_SHUTDOWN = NPT_ERROR_BASE_THREADS-0;
00024 const int NPT_ERROR_CALLBACK_NOTHING_PENDING  = NPT_ERROR_BASE_THREADS-1;
00025 
00026 /*----------------------------------------------------------------------
00027 |   NPT_MutexInterface
00028 +---------------------------------------------------------------------*/
00029 class NPT_MutexInterface
00030 {
00031  public:
00032     // methods
00033     virtual           ~NPT_MutexInterface() {}
00034     virtual NPT_Result Lock()   = 0;
00035     virtual NPT_Result Unlock() = 0;
00036 };
00037 
00038 /*----------------------------------------------------------------------
00039 |   NPT_Mutex
00040 +---------------------------------------------------------------------*/
00041 class NPT_Mutex : public NPT_MutexInterface
00042 {
00043  public:
00044     // methods
00045                NPT_Mutex();
00046               ~NPT_Mutex() { delete m_Delegate; }
00047     NPT_Result Lock()   { return m_Delegate->Lock();   }
00048     NPT_Result Unlock() { return m_Delegate->Unlock(); }
00049 
00050  private:
00051     // members
00052     NPT_MutexInterface* m_Delegate;
00053 };
00054 
00055 /*----------------------------------------------------------------------
00056 |   NPT_AutoLock
00057 +---------------------------------------------------------------------*/
00058 class NPT_AutoLock
00059 {
00060  public:
00061     // methods
00062      NPT_AutoLock(NPT_Mutex &mutex) : m_Mutex(mutex)   {
00063         m_Mutex.Lock();
00064     }
00065     ~NPT_AutoLock() {
00066         m_Mutex.Unlock(); 
00067     }
00068         
00069  private:
00070     // members
00071     NPT_Mutex& m_Mutex;
00072 };
00073 
00074 /*----------------------------------------------------------------------
00075 |   NPT_Lock
00076 +---------------------------------------------------------------------*/
00077 template <typename T> 
00078 class NPT_Lock : public T,
00079                  public NPT_Mutex
00080 {
00081 };
00082 
00083 /*----------------------------------------------------------------------
00084 |   NPT_SharedVariableInterface
00085 +---------------------------------------------------------------------*/
00086 class NPT_SharedVariableInterface
00087 {
00088  public:
00089     // methods
00090     virtual           ~NPT_SharedVariableInterface() {}
00091     virtual NPT_Result SetValue(NPT_Integer value)        = 0;
00092     virtual NPT_Result GetValue(NPT_Integer& value)       = 0;
00093     virtual NPT_Result WaitUntilEquals(NPT_Integer value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0;
00094     virtual NPT_Result WaitWhileEquals(NPT_Integer value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0;
00095 };
00096 
00097 /*----------------------------------------------------------------------
00098 |   NPT_SharedVariable
00099 +---------------------------------------------------------------------*/
00100 class NPT_SharedVariable : public NPT_SharedVariableInterface
00101 {
00102  public:
00103     // methods
00104                NPT_SharedVariable(NPT_Integer value = 0);
00105               ~NPT_SharedVariable() { delete m_Delegate; }
00106     NPT_Result SetValue(NPT_Integer value) { 
00107         return m_Delegate->SetValue(value); 
00108     }
00109     NPT_Result GetValue(NPT_Integer& value) { 
00110         return m_Delegate->GetValue(value); 
00111     }
00112     NPT_Result WaitUntilEquals(NPT_Integer value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { 
00113         return m_Delegate->WaitUntilEquals(value, timeout); 
00114     }
00115     NPT_Result WaitWhileEquals(NPT_Integer value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { 
00116         return m_Delegate->WaitWhileEquals(value, timeout); 
00117     }
00118 
00119  private:
00120     // members
00121     NPT_SharedVariableInterface* m_Delegate;
00122 };
00123 
00124 /*----------------------------------------------------------------------
00125 |   NPT_AtomicVariableInterface
00126 +---------------------------------------------------------------------*/
00127 class NPT_AtomicVariableInterface
00128 {
00129  public:
00130     // methods
00131     virtual             ~NPT_AtomicVariableInterface() {}
00132     virtual  NPT_Integer Increment() = 0;
00133     virtual  NPT_Integer Decrement() = 0;
00134     virtual  NPT_Integer GetValue()  = 0;
00135     virtual  void        SetValue(NPT_Integer value)  = 0;
00136 };
00137 
00138 /*----------------------------------------------------------------------
00139 |   NPT_AtomicVariable
00140 +---------------------------------------------------------------------*/
00141 class NPT_AtomicVariable : public NPT_AtomicVariableInterface
00142 {
00143  public:
00144     // methods
00145                 NPT_AtomicVariable(NPT_Integer value = 0);
00146                ~NPT_AtomicVariable()        { delete m_Delegate;             }
00147     NPT_Integer Increment()                 { return m_Delegate->Increment();}
00148     NPT_Integer Decrement()                 { return m_Delegate->Decrement();}
00149     void        SetValue(NPT_Integer value) { m_Delegate->SetValue(value);   }
00150     NPT_Integer GetValue()                  { return m_Delegate->GetValue(); }
00151 
00152  private:
00153     // members
00154     NPT_AtomicVariableInterface* m_Delegate;
00155 };
00156 
00157 /*----------------------------------------------------------------------
00158 |   NPT_Runnable
00159 +---------------------------------------------------------------------*/
00160 class NPT_Runnable
00161 {
00162 public:
00163     virtual ~NPT_Runnable() {}  
00164     virtual void Run() = 0;
00165 };
00166 
00167 /*----------------------------------------------------------------------
00168 |   NPT_ThreadInterface
00169 +---------------------------------------------------------------------*/
00170 class NPT_ThreadInterface: public NPT_Runnable, public NPT_Interruptible
00171 {
00172  public:
00173     // methods
00174     virtual           ~NPT_ThreadInterface() {}
00175     virtual NPT_Result Start() = 0;
00176     virtual NPT_Result Wait()  = 0;
00177 };
00178 
00179 /*----------------------------------------------------------------------
00180 |   NPT_Thread
00181 +---------------------------------------------------------------------*/
00182 class NPT_Thread : public NPT_ThreadInterface
00183 {
00184  public:
00185     // types
00186     typedef unsigned long ThreadId;
00187 
00188     // class methods
00189     static ThreadId GetCurrentThreadId();
00190 
00191     // methods
00192     NPT_Thread(bool detached = false);
00193     NPT_Thread(NPT_Runnable& target, bool detached = false);
00194    ~NPT_Thread() { delete m_Delegate; }
00195 
00196     // NPT_ThreadInterface methods
00197     NPT_Result Start() { return m_Delegate->Start(); } 
00198     NPT_Result Wait()  { return m_Delegate->Wait();  }
00199 
00200     // NPT_Runnable methods
00201     virtual void Run() {}
00202 
00203     // NPT_Interruptible methods
00204     virtual NPT_Result Interrupt() { return m_Delegate->Interrupt(); }
00205 
00206  private:
00207     // members
00208     NPT_ThreadInterface* m_Delegate;
00209 };
00210 
00211 
00212 /*----------------------------------------------------------------------
00213 |   NPT_ThreadCallbackReceiver
00214 +---------------------------------------------------------------------*/
00215 class NPT_ThreadCallbackReceiver
00216 {
00217 public:
00218     virtual ~NPT_ThreadCallbackReceiver() {}
00219     virtual void OnCallback(void* args) = 0;
00220 };
00221 
00222 /*----------------------------------------------------------------------
00223 |   NPT_ThreadCallbackSlot
00224 +---------------------------------------------------------------------*/
00225 class NPT_ThreadCallbackSlot
00226 {
00227 public:
00228     // types
00229     class NotificationHelper {
00230     public:
00231         virtual ~NotificationHelper() {};
00232         virtual void Notify(void) = 0;
00233     };
00234 
00235     // constructor
00236     NPT_ThreadCallbackSlot();
00237 
00238     // methods
00239     NPT_Result ReceiveCallback(NPT_ThreadCallbackReceiver& receiver, NPT_Timeout timeout = 0);
00240     NPT_Result SendCallback(void* args);
00241     NPT_Result SetNotificationHelper(NotificationHelper* helper);
00242     NPT_Result Shutdown();
00243 
00244 protected:
00245     // members
00246     volatile void*      m_CallbackArgs;
00247     volatile bool       m_Shutdown;
00248     NPT_SharedVariable  m_Pending;
00249     NPT_SharedVariable  m_Ack;
00250     NPT_Mutex           m_ReadLock;
00251     NPT_Mutex           m_WriteLock;
00252     NotificationHelper* m_NotificationHelper;
00253 };
00254 
00255 #endif // _NPT_THREADS_H_