#ifndef _NPT_THREADS_H_
#define _NPT_THREADS_H_
#include "NptTypes.h"
#include "NptConstants.h"
#include "NptInterfaces.h"
const int NPT_ERROR_CALLBACK_HANDLER_SHUTDOWN = NPT_ERROR_BASE_THREADS-0;
const int NPT_ERROR_CALLBACK_NOTHING_PENDING = NPT_ERROR_BASE_THREADS-1;
const int NPT_THREAD_PRIORITY_MIN = -15;
const int NPT_THREAD_PRIORITY_IDLE = -15;
const int NPT_THREAD_PRIORITY_LOWEST = -2;
const int NPT_THREAD_PRIORITY_BELOW_NORMAL = -1;
const int NPT_THREAD_PRIORITY_NORMAL = 0;
const int NPT_THREAD_PRIORITY_ABOVE_NORMAL = 1;
const int NPT_THREAD_PRIORITY_HIGHEST = 2;
const int NPT_THREAD_PRIORITY_TIME_CRITICAL = 15;
const int NPT_THREAD_PRIORITY_MAX = 15;
class NPT_MutexInterface
{
public:
virtual ~NPT_MutexInterface() {}
virtual NPT_Result Lock() = 0;
virtual NPT_Result Unlock() = 0;
};
class NPT_Mutex : public NPT_MutexInterface
{
public:
NPT_Mutex();
~NPT_Mutex() { delete m_Delegate; }
NPT_Result Lock() { return m_Delegate->Lock(); }
NPT_Result Unlock() { return m_Delegate->Unlock(); }
private:
NPT_MutexInterface* m_Delegate;
};
class NPT_AutoLock
{
public:
NPT_AutoLock(NPT_Mutex &mutex) : m_Mutex(mutex) {
m_Mutex.Lock();
}
~NPT_AutoLock() {
m_Mutex.Unlock();
}
private:
NPT_Mutex& m_Mutex;
};
template <typename T>
class NPT_Lock : public T,
public NPT_Mutex
{
};
class NPT_SingletonLock
{
public:
static NPT_Mutex& GetInstance() {
return Instance;
}
private:
static NPT_Mutex Instance;
};
class NPT_SharedVariableInterface
{
public:
virtual ~NPT_SharedVariableInterface() {}
virtual void SetValue(int value)= 0;
virtual int GetValue() = 0;
virtual NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0;
virtual NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0;
};
class NPT_SharedVariable : public NPT_SharedVariableInterface
{
public:
NPT_SharedVariable(int value = 0);
~NPT_SharedVariable() { delete m_Delegate; }
void SetValue(int value) {
m_Delegate->SetValue(value);
}
int GetValue() {
return m_Delegate->GetValue();
}
NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) {
return m_Delegate->WaitUntilEquals(value, timeout);
}
NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) {
return m_Delegate->WaitWhileEquals(value, timeout);
}
private:
NPT_SharedVariableInterface* m_Delegate;
};
class NPT_AtomicVariableInterface
{
public:
virtual ~NPT_AtomicVariableInterface() {}
virtual int Increment() = 0;
virtual int Decrement() = 0;
virtual int GetValue() = 0;
virtual void SetValue(int value) = 0;
};
class NPT_AtomicVariable : public NPT_AtomicVariableInterface
{
public:
NPT_AtomicVariable(int value = 0);
~NPT_AtomicVariable() { delete m_Delegate; }
int Increment() { return m_Delegate->Increment();}
int Decrement() { return m_Delegate->Decrement();}
void SetValue(int value) { m_Delegate->SetValue(value); }
int GetValue() { return m_Delegate->GetValue(); }
private:
NPT_AtomicVariableInterface* m_Delegate;
};
class NPT_Runnable
{
public:
virtual ~NPT_Runnable() {}
virtual void Run() = 0;
};
class NPT_ThreadInterface: public NPT_Runnable, public NPT_Interruptible
{
public:
virtual ~NPT_ThreadInterface() {}
virtual NPT_Result Start() = 0;
virtual NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0;
virtual NPT_Result SetPriority(int ) { return NPT_SUCCESS; }
virtual NPT_Result GetPriority(int& priority) = 0;
};
class NPT_Thread : public NPT_ThreadInterface
{
public:
typedef unsigned long ThreadId;
static ThreadId GetCurrentThreadId();
static NPT_Result SetCurrentThreadPriority(int priority);
static NPT_Result GetCurrentThreadPriority(int& priority);
explicit NPT_Thread(bool detached = false);
explicit NPT_Thread(NPT_Runnable& target, bool detached = false);
~NPT_Thread() { delete m_Delegate; }
NPT_Result Start() {
return m_Delegate->Start();
}
NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) {
return m_Delegate->Wait(timeout);
}
NPT_Result SetPriority(int priority) {
return m_Delegate->SetPriority(priority);
}
NPT_Result GetPriority(int& priority) {
return m_Delegate->GetPriority(priority);
}
virtual void Run() {}
virtual NPT_Result Interrupt() { return m_Delegate->Interrupt(); }
private:
NPT_ThreadInterface* m_Delegate;
};
class NPT_ThreadCallbackReceiver
{
public:
virtual ~NPT_ThreadCallbackReceiver() {}
virtual void OnCallback(void* args) = 0;
};
class NPT_ThreadCallbackSlot
{
public:
class NotificationHelper {
public:
virtual ~NotificationHelper() {};
virtual void Notify(void) = 0;
};
NPT_ThreadCallbackSlot();
NPT_Result ReceiveCallback(NPT_ThreadCallbackReceiver& receiver, NPT_Timeout timeout = 0);
NPT_Result SendCallback(void* args);
NPT_Result SetNotificationHelper(NotificationHelper* helper);
NPT_Result Shutdown();
protected:
volatile void* m_CallbackArgs;
volatile bool m_Shutdown;
NPT_SharedVariable m_Pending;
NPT_SharedVariable m_Ack;
NPT_Mutex m_ReadLock;
NPT_Mutex m_WriteLock;
NotificationHelper* m_NotificationHelper;
};
#endif