]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengine.h
start of fix for bug #805
[user/henk/code/inspircd.git] / include / threadengine.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef __THREADENGINE__
15 #define __THREADENGINE__
16
17 #include <vector>
18 #include <string>
19 #include <map>
20 #include "inspircd_config.h"
21 #include "base.h"
22
23 #ifdef WINDOWS
24 #include "threadengines/threadengine_win32.h"
25 #endif
26
27 class ThreadData;
28
29 /** Derive from this class to implement your own threaded sections of
30  * code. Be sure to keep your code thread-safe and not prone to deadlocks
31  * and race conditions if you MUST use threading!
32  */
33 class CoreExport Thread : public Extensible
34 {
35  private:
36         /** Set to true when the thread is to exit
37          */
38         bool ExitFlag;
39  protected:
40         /** Get thread's current exit status.
41          * (are we being asked to exit?)
42          */
43         bool GetExitFlag()
44         {
45                 return ExitFlag;
46         }
47  public:
48         /** Opaque thread state managed by threading engine
49          */
50         ThreadData* state;
51
52         /** Set Creator to NULL at this point
53          */
54         Thread() : ExitFlag(false), state(NULL)
55         {
56         }
57
58         virtual ~Thread();
59
60         /** Override this method to put your actual
61          * threaded code here.
62          */
63         virtual void Run() = 0;
64
65         /** Signal the thread to exit gracefully.
66          */
67         virtual void SetExitFlag()
68         {
69                 ExitFlag = true;
70         }
71 };
72
73
74 class CoreExport QueuedThread : public Thread
75 {
76         ThreadQueueData queue;
77  protected:
78         /** Waits for an enqueue operation to complete
79          * You MUST hold the queue lock when you call this.
80          * It will be unlocked while you wait, and will be relocked
81          * before the function returns
82          */
83         void WaitForQueue()
84         {
85                 queue.Wait();
86         }
87  public:
88         /** Lock queue.
89          */
90         void LockQueue()
91         {
92                 queue.Lock();
93         }
94         /** Unlock queue.
95          */
96         void UnlockQueue()
97         {
98                 queue.Unlock();
99         }
100         /** Unlock queue and wake up worker
101          */
102         void UnlockQueueWakeup()
103         {
104                 queue.Wakeup();
105                 queue.Unlock();
106         }
107         virtual void SetExitFlag()
108         {
109                 queue.Lock();
110                 Thread::SetExitFlag();
111                 queue.Wakeup();
112                 queue.Unlock();
113         }
114 };
115
116 class CoreExport SocketThread : public Thread
117 {
118         ThreadQueueData queue;
119         ThreadSignalData signal;
120  protected:
121         /** Waits for an enqueue operation to complete
122          * You MUST hold the queue lock when you call this.
123          * It will be unlocked while you wait, and will be relocked
124          * before the function returns
125          */
126         void WaitForQueue()
127         {
128                 queue.Wait();
129         }
130         /** Notifies parent by making the SignalFD ready to read
131          * No requirements on locking
132          */
133         void NotifyParent();
134  public:
135         SocketThread(InspIRCd* SI);
136         virtual ~SocketThread();
137         /** Lock queue.
138          */
139         void LockQueue()
140         {
141                 queue.Lock();
142         }
143         /** Unlock queue.
144          */
145         void UnlockQueue()
146         {
147                 queue.Unlock();
148         }
149         /** Unlock queue and send wakeup to worker
150          */
151         void UnlockQueueWakeup()
152         {
153                 queue.Wakeup();
154                 queue.Unlock();
155         }
156         virtual void SetExitFlag()
157         {
158                 queue.Lock();
159                 Thread::SetExitFlag();
160                 queue.Wakeup();
161                 queue.Unlock();
162         }
163
164         /**
165          * Called in the context of the parent thread after a notification
166          * has passed through the socket
167          */
168         virtual void OnNotify() = 0;
169 };
170
171 #endif
172