1 /***************************************************************** 2 | 3 | Neptune - Threads 4 | 5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of Axiomatic Systems nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 ****************************************************************/ 31 32 #ifndef _NPT_THREADS_H_ 33 #define _NPT_THREADS_H_ 34 35 /*---------------------------------------------------------------------- 36 | includes 37 +---------------------------------------------------------------------*/ 38 #include "NptTypes.h" 39 #include "NptConstants.h" 40 #include "NptInterfaces.h" 41 42 /*---------------------------------------------------------------------- 43 | error codes 44 +---------------------------------------------------------------------*/ 45 const int NPT_ERROR_CALLBACK_HANDLER_SHUTDOWN = NPT_ERROR_BASE_THREADS-0; 46 const int NPT_ERROR_CALLBACK_NOTHING_PENDING = NPT_ERROR_BASE_THREADS-1; 47 48 /*---------------------------------------------------------------------- 49 | constants 50 +---------------------------------------------------------------------*/ 51 const int NPT_THREAD_PRIORITY_MIN = -15; 52 const int NPT_THREAD_PRIORITY_IDLE = -15; 53 const int NPT_THREAD_PRIORITY_LOWEST = -2; 54 const int NPT_THREAD_PRIORITY_BELOW_NORMAL = -1; 55 const int NPT_THREAD_PRIORITY_NORMAL = 0; 56 const int NPT_THREAD_PRIORITY_ABOVE_NORMAL = 1; 57 const int NPT_THREAD_PRIORITY_HIGHEST = 2; 58 const int NPT_THREAD_PRIORITY_TIME_CRITICAL = 15; 59 const int NPT_THREAD_PRIORITY_MAX = 15; 60 61 /*---------------------------------------------------------------------- 62 | NPT_MutexInterface 63 +---------------------------------------------------------------------*/ 64 class NPT_MutexInterface 65 { 66 public: 67 // methods ~NPT_MutexInterface()68 virtual ~NPT_MutexInterface() {} 69 virtual NPT_Result Lock() = 0; 70 virtual NPT_Result Unlock() = 0; 71 }; 72 73 /*---------------------------------------------------------------------- 74 | NPT_Mutex 75 +---------------------------------------------------------------------*/ 76 class NPT_Mutex : public NPT_MutexInterface 77 { 78 public: 79 // methods 80 NPT_Mutex(bool recursive = false); ~NPT_Mutex()81 ~NPT_Mutex() { delete m_Delegate; } Lock()82 NPT_Result Lock() { return m_Delegate->Lock(); } Unlock()83 NPT_Result Unlock() { return m_Delegate->Unlock(); } 84 85 private: 86 // members 87 NPT_MutexInterface* m_Delegate; 88 }; 89 90 /*---------------------------------------------------------------------- 91 | NPT_AutoLock 92 +---------------------------------------------------------------------*/ 93 class NPT_AutoLock 94 { 95 public: 96 // methods NPT_AutoLock(NPT_Mutex & mutex)97 NPT_AutoLock(NPT_Mutex &mutex) : m_Mutex(mutex) { 98 m_Mutex.Lock(); 99 } ~NPT_AutoLock()100 ~NPT_AutoLock() { 101 m_Mutex.Unlock(); 102 } 103 104 private: 105 // members 106 NPT_Mutex& m_Mutex; 107 }; 108 109 /*---------------------------------------------------------------------- 110 | NPT_Lock 111 +---------------------------------------------------------------------*/ 112 template <typename T> 113 class NPT_Lock : public T, 114 public NPT_Mutex 115 { 116 }; 117 118 /*---------------------------------------------------------------------- 119 | NPT_SingletonLock 120 +---------------------------------------------------------------------*/ 121 class NPT_SingletonLock 122 { 123 public: GetInstance()124 static NPT_Mutex& GetInstance() { 125 return Instance; 126 } 127 128 private: 129 static NPT_Mutex Instance; 130 }; 131 132 /*---------------------------------------------------------------------- 133 | NPT_SharedVariableInterface 134 +---------------------------------------------------------------------*/ 135 class NPT_SharedVariableInterface 136 { 137 public: 138 // methods ~NPT_SharedVariableInterface()139 virtual ~NPT_SharedVariableInterface() {} 140 virtual void SetValue(int value)= 0; 141 virtual int GetValue() = 0; 142 virtual NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; 143 virtual NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; 144 }; 145 146 /*---------------------------------------------------------------------- 147 | NPT_SharedVariable 148 +---------------------------------------------------------------------*/ 149 class NPT_SharedVariable : public NPT_SharedVariableInterface 150 { 151 public: 152 // methods 153 NPT_SharedVariable(int value = 0); ~NPT_SharedVariable()154 ~NPT_SharedVariable() { delete m_Delegate; } SetValue(int value)155 void SetValue(int value) { 156 m_Delegate->SetValue(value); 157 } GetValue()158 int GetValue() { 159 return m_Delegate->GetValue(); 160 } 161 NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { 162 return m_Delegate->WaitUntilEquals(value, timeout); 163 } 164 NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { 165 return m_Delegate->WaitWhileEquals(value, timeout); 166 } 167 168 private: 169 // members 170 NPT_SharedVariableInterface* m_Delegate; 171 }; 172 173 /*---------------------------------------------------------------------- 174 | NPT_AtomicVariableInterface 175 +---------------------------------------------------------------------*/ 176 class NPT_AtomicVariableInterface 177 { 178 public: 179 // methods ~NPT_AtomicVariableInterface()180 virtual ~NPT_AtomicVariableInterface() {} 181 virtual int Increment() = 0; 182 virtual int Decrement() = 0; 183 virtual int GetValue() = 0; 184 virtual void SetValue(int value) = 0; 185 }; 186 187 /*---------------------------------------------------------------------- 188 | NPT_AtomicVariable 189 +---------------------------------------------------------------------*/ 190 class NPT_AtomicVariable : public NPT_AtomicVariableInterface 191 { 192 public: 193 // methods 194 NPT_AtomicVariable(int value = 0); ~NPT_AtomicVariable()195 ~NPT_AtomicVariable() { delete m_Delegate; } Increment()196 int Increment() { return m_Delegate->Increment();} Decrement()197 int Decrement() { return m_Delegate->Decrement();} SetValue(int value)198 void SetValue(int value) { m_Delegate->SetValue(value); } GetValue()199 int GetValue() { return m_Delegate->GetValue(); } 200 201 private: 202 // members 203 NPT_AtomicVariableInterface* m_Delegate; 204 }; 205 206 /*---------------------------------------------------------------------- 207 | NPT_Runnable 208 +---------------------------------------------------------------------*/ 209 class NPT_Runnable 210 { 211 public: ~NPT_Runnable()212 virtual ~NPT_Runnable() {} 213 virtual void Run() = 0; 214 }; 215 216 /*---------------------------------------------------------------------- 217 | NPT_ThreadInterface 218 +---------------------------------------------------------------------*/ 219 class NPT_ThreadInterface: public NPT_Runnable, public NPT_Interruptible 220 { 221 public: 222 // methods ~NPT_ThreadInterface()223 virtual ~NPT_ThreadInterface() {} 224 virtual NPT_Result Start() = 0; 225 virtual NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; SetPriority(int)226 virtual NPT_Result SetPriority(int /*priority*/) { return NPT_SUCCESS; } 227 virtual NPT_Result CancelBlockerSocket() = 0; 228 virtual NPT_Result GetPriority(int& priority) = 0; 229 }; 230 231 /*---------------------------------------------------------------------- 232 | NPT_Thread 233 +---------------------------------------------------------------------*/ 234 class NPT_Thread : public NPT_ThreadInterface 235 { 236 public: 237 // types 238 typedef NPT_UInt64 ThreadId; 239 240 // class methods 241 static ThreadId GetCurrentThreadId(); 242 static NPT_Result SetCurrentThreadPriority(int priority); 243 static NPT_Result GetCurrentThreadPriority(int& priority); 244 245 // methods 246 explicit NPT_Thread(bool detached = false); 247 explicit NPT_Thread(NPT_Runnable& target, bool detached = false); ~NPT_Thread()248 ~NPT_Thread() { delete m_Delegate; } 249 250 // cancel any socket that this thread may be waiting for CancelBlockerSocket()251 NPT_Result CancelBlockerSocket() { return m_Delegate->CancelBlockerSocket(); } 252 253 // NPT_ThreadInterface methods Start()254 NPT_Result Start() { 255 return m_Delegate->Start(); 256 } 257 NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { 258 return m_Delegate->Wait(timeout); 259 } SetPriority(int priority)260 NPT_Result SetPriority(int priority) { 261 return m_Delegate->SetPriority(priority); 262 } GetPriority(int & priority)263 NPT_Result GetPriority(int& priority) { 264 return m_Delegate->GetPriority(priority); 265 } 266 267 // NPT_Runnable methods Run()268 virtual void Run() {} 269 270 // NPT_Interruptible methods Interrupt()271 virtual NPT_Result Interrupt() { return m_Delegate->Interrupt(); } 272 273 private: 274 // members 275 NPT_ThreadInterface* m_Delegate; 276 }; 277 278 279 /*---------------------------------------------------------------------- 280 | NPT_ThreadCallbackReceiver 281 +---------------------------------------------------------------------*/ 282 class NPT_ThreadCallbackReceiver 283 { 284 public: ~NPT_ThreadCallbackReceiver()285 virtual ~NPT_ThreadCallbackReceiver() {} 286 virtual void OnCallback(void* args) = 0; 287 }; 288 289 /*---------------------------------------------------------------------- 290 | NPT_ThreadCallbackSlot 291 +---------------------------------------------------------------------*/ 292 class NPT_ThreadCallbackSlot 293 { 294 public: 295 // types 296 class NotificationHelper { 297 public: ~NotificationHelper()298 virtual ~NotificationHelper() {}; 299 virtual void Notify(void) = 0; 300 }; 301 302 // constructor 303 NPT_ThreadCallbackSlot(); 304 305 // methods 306 NPT_Result ReceiveCallback(NPT_ThreadCallbackReceiver& receiver, NPT_Timeout timeout = 0); 307 NPT_Result SendCallback(void* args); 308 NPT_Result SetNotificationHelper(NotificationHelper* helper); 309 NPT_Result Shutdown(); 310 311 protected: 312 // members 313 volatile void* m_CallbackArgs; 314 volatile bool m_Shutdown; 315 NPT_SharedVariable m_Pending; 316 NPT_SharedVariable m_Ack; 317 NPT_Mutex m_ReadLock; 318 NPT_Mutex m_WriteLock; 319 NotificationHelper* m_NotificationHelper; 320 }; 321 322 #endif // _NPT_THREADS_H_ 323