]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengine.h
Merge pull request #96 from Justasic/insp20
[user/henk/code/inspircd.git] / include / threadengine.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #ifndef THREADENGINE_H
22 #define THREADENGINE_H
23
24 #include <vector>
25 #include <string>
26 #include <map>
27 #include "inspircd_config.h"
28 #include "base.h"
29
30 #ifdef WINDOWS
31 #include "threadengines/threadengine_win32.h"
32 #endif
33
34 class ThreadData;
35
36 /** Derive from this class to implement your own threaded sections of
37  * code. Be sure to keep your code thread-safe and not prone to deadlocks
38  * and race conditions if you MUST use threading!
39  */
40 class CoreExport Thread
41 {
42  private:
43         /** Set to true when the thread is to exit
44          */
45         bool ExitFlag;
46  protected:
47         /** Get thread's current exit status.
48          * (are we being asked to exit?)
49          */
50         bool GetExitFlag()
51         {
52                 return ExitFlag;
53         }
54  public:
55         /** Opaque thread state managed by threading engine
56          */
57         ThreadData* state;
58
59         /** Set Creator to NULL at this point
60          */
61         Thread() : ExitFlag(false), state(NULL)
62         {
63         }
64
65         /* If the thread is running, you MUST join BEFORE deletion */
66         virtual ~Thread();
67
68         /** Override this method to put your actual
69          * threaded code here.
70          */
71         virtual void Run() = 0;
72
73         /** Signal the thread to exit gracefully.
74          */
75         virtual void SetExitFlag();
76
77         /** Join the thread (calls SetExitFlag and waits for exit)
78          */
79         void join();
80 };
81
82
83 class CoreExport QueuedThread : public Thread
84 {
85         ThreadQueueData queue;
86  protected:
87         /** Waits for an enqueue operation to complete
88          * You MUST hold the queue lock when you call this.
89          * It will be unlocked while you wait, and will be relocked
90          * before the function returns
91          */
92         void WaitForQueue()
93         {
94                 queue.Wait();
95         }
96  public:
97         /** Lock queue.
98          */
99         void LockQueue()
100         {
101                 queue.Lock();
102         }
103         /** Unlock queue.
104          */
105         void UnlockQueue()
106         {
107                 queue.Unlock();
108         }
109         /** Unlock queue and wake up worker
110          */
111         void UnlockQueueWakeup()
112         {
113                 queue.Wakeup();
114                 queue.Unlock();
115         }
116         virtual void SetExitFlag()
117         {
118                 queue.Lock();
119                 Thread::SetExitFlag();
120                 queue.Wakeup();
121                 queue.Unlock();
122         }
123 };
124
125 class CoreExport SocketThread : public Thread
126 {
127         ThreadQueueData queue;
128         ThreadSignalData signal;
129  protected:
130         /** Waits for an enqueue operation to complete
131          * You MUST hold the queue lock when you call this.
132          * It will be unlocked while you wait, and will be relocked
133          * before the function returns
134          */
135         void WaitForQueue()
136         {
137                 queue.Wait();
138         }
139  public:
140         /** Notifies parent by making the SignalFD ready to read
141          * No requirements on locking
142          */
143         void NotifyParent();
144         SocketThread();
145         virtual ~SocketThread();
146         /** Lock queue.
147          */
148         void LockQueue()
149         {
150                 queue.Lock();
151         }
152         /** Unlock queue.
153          */
154         void UnlockQueue()
155         {
156                 queue.Unlock();
157         }
158         /** Unlock queue and send wakeup to worker
159          */
160         void UnlockQueueWakeup()
161         {
162                 queue.Wakeup();
163                 queue.Unlock();
164         }
165         virtual void SetExitFlag()
166         {
167                 queue.Lock();
168                 Thread::SetExitFlag();
169                 queue.Wakeup();
170                 queue.Unlock();
171         }
172
173         /**
174          * Called in the context of the parent thread after a notification
175          * has passed through the socket
176          */
177         virtual void OnNotify() = 0;
178 };
179
180 #endif
181