1 /*****************************************************************
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
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.
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.
30 ****************************************************************/
32 #ifndef _NPT_THREADS_H_
33 #define _NPT_THREADS_H_
35 /*----------------------------------------------------------------------
37 +---------------------------------------------------------------------*/
39 #include "NptConstants.h"
40 #include "NptInterfaces.h"
42 /*----------------------------------------------------------------------
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;
48 /*----------------------------------------------------------------------
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;
61 /*----------------------------------------------------------------------
63 +---------------------------------------------------------------------*/
64 class NPT_MutexInterface
68 virtual ~NPT_MutexInterface() {}
69 virtual NPT_Result
Lock() = 0;
70 virtual NPT_Result
Unlock() = 0;
73 /*----------------------------------------------------------------------
75 +---------------------------------------------------------------------*/
76 class NPT_Mutex
: public NPT_MutexInterface
80 NPT_Mutex(bool recursive
= false);
81 ~NPT_Mutex() override
{ delete m_Delegate
; }
82 NPT_Result
Lock() override
{ return m_Delegate
->Lock(); }
83 NPT_Result
Unlock() override
{ return m_Delegate
->Unlock(); }
87 NPT_MutexInterface
* m_Delegate
;
90 /*----------------------------------------------------------------------
92 +---------------------------------------------------------------------*/
97 NPT_AutoLock(NPT_Mutex
&mutex
) : m_Mutex(mutex
) {
109 /*----------------------------------------------------------------------
111 +---------------------------------------------------------------------*/
112 template <typename T
>
113 class NPT_Lock
: public T
,
118 /*----------------------------------------------------------------------
120 +---------------------------------------------------------------------*/
121 class NPT_SingletonLock
124 static NPT_Mutex
& GetInstance() {
129 static NPT_Mutex Instance
;
132 /*----------------------------------------------------------------------
133 | NPT_SharedVariableInterface
134 +---------------------------------------------------------------------*/
135 class 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;
146 /*----------------------------------------------------------------------
148 +---------------------------------------------------------------------*/
149 class NPT_SharedVariable
: public NPT_SharedVariableInterface
153 NPT_SharedVariable(int value
= 0);
154 ~NPT_SharedVariable() override
{ delete m_Delegate
; }
155 void SetValue(int value
) override
{
156 m_Delegate
->SetValue(value
);
158 int GetValue() override
{
159 return m_Delegate
->GetValue();
161 NPT_Result
WaitUntilEquals(int value
, NPT_Timeout timeout
= NPT_TIMEOUT_INFINITE
) override
{
162 return m_Delegate
->WaitUntilEquals(value
, timeout
);
164 NPT_Result
WaitWhileEquals(int value
, NPT_Timeout timeout
= NPT_TIMEOUT_INFINITE
) override
{
165 return m_Delegate
->WaitWhileEquals(value
, timeout
);
170 NPT_SharedVariableInterface
* m_Delegate
;
173 /*----------------------------------------------------------------------
174 | NPT_AtomicVariableInterface
175 +---------------------------------------------------------------------*/
176 class 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;
187 /*----------------------------------------------------------------------
189 +---------------------------------------------------------------------*/
190 class NPT_AtomicVariable
: public NPT_AtomicVariableInterface
194 NPT_AtomicVariable(int value
= 0);
195 ~NPT_AtomicVariable() override
{ delete m_Delegate
; }
196 int Increment() override
{ return m_Delegate
->Increment();}
197 int Decrement() override
{ return m_Delegate
->Decrement();}
198 void SetValue(int value
) override
{ m_Delegate
->SetValue(value
); }
199 int GetValue() override
{ return m_Delegate
->GetValue(); }
203 NPT_AtomicVariableInterface
* m_Delegate
;
206 /*----------------------------------------------------------------------
208 +---------------------------------------------------------------------*/
212 virtual ~NPT_Runnable() {}
213 virtual void Run() = 0;
216 /*----------------------------------------------------------------------
217 | NPT_ThreadInterface
218 +---------------------------------------------------------------------*/
219 class NPT_ThreadInterface
: public NPT_Runnable
, public NPT_Interruptible
223 ~NPT_ThreadInterface() override
{}
224 virtual NPT_Result
Start() = 0;
225 virtual NPT_Result
Wait(NPT_Timeout timeout
= NPT_TIMEOUT_INFINITE
) = 0;
226 virtual NPT_Result
SetPriority(int /*priority*/) { return NPT_SUCCESS
; }
227 virtual NPT_Result
CancelBlockerSocket() = 0;
228 virtual NPT_Result
GetPriority(int& priority
) = 0;
231 /*----------------------------------------------------------------------
233 +---------------------------------------------------------------------*/
234 class NPT_Thread
: public NPT_ThreadInterface
238 typedef NPT_UInt64 ThreadId
;
241 static ThreadId
GetCurrentThreadId();
242 static NPT_Result
SetCurrentThreadPriority(int priority
);
243 static NPT_Result
GetCurrentThreadPriority(int& priority
);
246 explicit NPT_Thread(bool detached
= false);
247 explicit NPT_Thread(NPT_Runnable
& target
, bool detached
= false);
248 ~NPT_Thread() override
{ delete m_Delegate
; }
250 // cancel any socket that this thread may be waiting for
251 NPT_Result
CancelBlockerSocket() override
{ return m_Delegate
->CancelBlockerSocket(); }
253 // NPT_ThreadInterface methods
254 NPT_Result
Start() override
{
255 return m_Delegate
->Start();
257 NPT_Result
Wait(NPT_Timeout timeout
= NPT_TIMEOUT_INFINITE
) override
{
258 return m_Delegate
->Wait(timeout
);
260 NPT_Result
SetPriority(int priority
) override
{
261 return m_Delegate
->SetPriority(priority
);
263 NPT_Result
GetPriority(int& priority
) override
{
264 return m_Delegate
->GetPriority(priority
);
267 // NPT_Runnable methods
268 void Run() override
{}
270 // NPT_Interruptible methods
271 NPT_Result
Interrupt() override
{ return m_Delegate
->Interrupt(); }
275 NPT_ThreadInterface
* m_Delegate
;
279 /*----------------------------------------------------------------------
280 | NPT_ThreadCallbackReceiver
281 +---------------------------------------------------------------------*/
282 class NPT_ThreadCallbackReceiver
285 virtual ~NPT_ThreadCallbackReceiver() {}
286 virtual void OnCallback(void* args
) = 0;
289 /*----------------------------------------------------------------------
290 | NPT_ThreadCallbackSlot
291 +---------------------------------------------------------------------*/
292 class NPT_ThreadCallbackSlot
296 class NotificationHelper
{
298 virtual ~NotificationHelper() {};
299 virtual void Notify(void) = 0;
303 NPT_ThreadCallbackSlot();
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();
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
;
322 #endif // _NPT_THREADS_H_