summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/threadengine.h111
-rw-r--r--include/threadengines/threadengine_pthread.h46
-rw-r--r--include/threadengines/threadengine_win32.h49
3 files changed, 200 insertions, 6 deletions
diff --git a/include/threadengine.h b/include/threadengine.h
index 27060ebe9..d7eaaef69 100644
--- a/include/threadengine.h
+++ b/include/threadengine.h
@@ -30,6 +30,15 @@ class CoreExport Thread : public Extensible
/** Set to true when the thread is to exit
*/
bool ExitFlag;
+// TODO protected:
+ public:
+ /** Get thread's current exit status.
+ * (are we being asked to exit?)
+ */
+ bool GetExitFlag()
+ {
+ return ExitFlag;
+ }
public:
/** Opaque thread state managed by threading engine
*/
@@ -60,18 +69,108 @@ class CoreExport Thread : public Extensible
/** Signal the thread to exit gracefully.
*/
- void SetExitFlag(bool value)
+ virtual void SetExitFlag()
{
- ExitFlag = value;
+ ExitFlag = true;
}
+};
- /** Get thread's current exit status.
- * (are we being asked to exit?)
+
+class CoreExport QueuedThread : public Thread
+{
+ ThreadQueueData queue;
+ protected:
+ /** Waits for an enqueue operation to complete
+ * You MUST hold the queue lock when you call this.
+ * It will be unlocked while you wait, and will be relocked
+ * before the function returns
*/
- bool GetExitFlag()
+ void WaitForQueue()
{
- return ExitFlag;
+ queue.Wait();
+ }
+ public:
+ /** Lock queue.
+ */
+ void LockQueue()
+ {
+ queue.Lock();
+ }
+ /** Unlock queue.
+ */
+ void UnlockQueue()
+ {
+ queue.Unlock();
+ }
+ /** Unlock queue and wake up worker
+ */
+ void UnlockQueueWakeup()
+ {
+ queue.Wakeup();
+ queue.Unlock();
+ }
+ virtual void SetExitFlag()
+ {
+ queue.Lock();
+ Thread::SetExitFlag();
+ queue.Wakeup();
+ queue.Unlock();
+ }
+};
+
+class CoreExport SocketThread : public Thread
+{
+ ThreadQueueData queue;
+ ThreadSignalData signal;
+ protected:
+ /** Waits for an enqueue operation to complete
+ * You MUST hold the queue lock when you call this.
+ * It will be unlocked while you wait, and will be relocked
+ * before the function returns
+ */
+ void WaitForQueue()
+ {
+ queue.Wait();
+ }
+ /** Notifies parent by making the SignalFD ready to read
+ * No requirements on locking
+ */
+ void NotifyParent();
+ public:
+ SocketThread(InspIRCd* SI);
+ virtual ~SocketThread();
+ /** Lock queue.
+ */
+ void LockQueue()
+ {
+ queue.Lock();
+ }
+ /** Unlock queue.
+ */
+ void UnlockQueue()
+ {
+ queue.Unlock();
+ }
+ /** Unlock queue and send wakeup to worker
+ */
+ void UnlockQueueWakeup()
+ {
+ queue.Wakeup();
+ queue.Unlock();
+ }
+ virtual void SetExitFlag()
+ {
+ queue.Lock();
+ Thread::SetExitFlag();
+ queue.Wakeup();
+ queue.Unlock();
}
+
+ /**
+ * Called in the context of the parent thread after a notification
+ * has passed through the socket
+ */
+ virtual void OnNotify() = 0;
};
#endif
diff --git a/include/threadengines/threadengine_pthread.h b/include/threadengines/threadengine_pthread.h
index 2aba4cb15..bad263d18 100644
--- a/include/threadengines/threadengine_pthread.h
+++ b/include/threadengines/threadengine_pthread.h
@@ -107,4 +107,50 @@ class CoreExport Mutex
}
};
+class ThreadQueueData
+{
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ public:
+ ThreadQueueData()
+ {
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond, NULL);
+ }
+
+ ~ThreadQueueData()
+ {
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&cond);
+ }
+
+ void Lock()
+ {
+ pthread_mutex_lock(&mutex);
+ }
+
+ void Unlock()
+ {
+ pthread_mutex_unlock(&mutex);
+ }
+
+ void Wakeup()
+ {
+ pthread_cond_signal(&cond);
+ }
+
+ void Wait()
+ {
+ pthread_cond_wait(&cond, &mutex);
+ }
+};
+
+class ThreadSignalSocket;
+class ThreadSignalData
+{
+ public:
+ ThreadSignalSocket* sock;
+};
+
+
#endif
diff --git a/include/threadengines/threadengine_win32.h b/include/threadengines/threadengine_win32.h
index c1f9f2cce..0fc9b27bc 100644
--- a/include/threadengines/threadengine_win32.h
+++ b/include/threadengines/threadengine_win32.h
@@ -95,5 +95,54 @@ class CoreExport Mutex
}
};
+class ThreadQueueData
+{
+ CRITICAL_SECTION mutex;
+ HANDLE event;
+ public:
+ ThreadQueueData()
+ {
+ InitializeCriticalSection(&mutex);
+ event = CreateEvent(NULL, false, false, NULL);
+ }
+
+ ~ThreadQueueData()
+ {
+ DeleteCriticalSection(&mutex);
+ }
+
+ void Lock()
+ {
+ EnterCriticalSection(&mutex);
+ }
+
+ void Unlock()
+ {
+ LeaveCriticalSection(&mutex);
+ }
+
+ void Wakeup()
+ {
+ PulseEvent(event);
+ }
+
+ void Wait()
+ {
+ LeaveCriticalSection(&mutex);
+ WaitForSingleObject(event, INFINITE);
+ EnterCriticalSection(&mutex);
+ }
+};
+
+class ThreadSignalData
+{
+ public:
+ int connFD;
+ ThreadSignalData()
+ {
+ connFD = -1;
+ }
+};
+
#endif