]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengine.h
Windows: In-depth cleanup (see details)
[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 class ThreadData;
31
32 /** Derive from this class to implement your own threaded sections of
33  * code. Be sure to keep your code thread-safe and not prone to deadlocks
34  * and race conditions if you MUST use threading!
35  */
36 class CoreExport Thread
37 {
38  private:
39         /** Set to true when the thread is to exit
40          */
41         bool ExitFlag;
42  protected:
43         /** Get thread's current exit status.
44          * (are we being asked to exit?)
45          */
46         bool GetExitFlag()
47         {
48                 return ExitFlag;
49         }
50  public:
51         /** Opaque thread state managed by threading engine
52          */
53         ThreadData* state;
54
55         /** Set Creator to NULL at this point
56          */
57         Thread() : ExitFlag(false), state(NULL)
58         {
59         }
60
61         /* If the thread is running, you MUST join BEFORE deletion */
62         virtual ~Thread();
63
64         /** Override this method to put your actual
65          * threaded code here.
66          */
67         virtual void Run() = 0;
68
69         /** Signal the thread to exit gracefully.
70          */
71         virtual void SetExitFlag();
72
73         /** Join the thread (calls SetExitFlag and waits for exit)
74          */
75         void join();
76 };
77
78
79 class CoreExport QueuedThread : public Thread
80 {
81         ThreadQueueData queue;
82  protected:
83         /** Waits for an enqueue operation to complete
84          * You MUST hold the queue lock when you call this.
85          * It will be unlocked while you wait, and will be relocked
86          * before the function returns
87          */
88         void WaitForQueue()
89         {
90                 queue.Wait();
91         }
92  public:
93         /** Lock queue.
94          */
95         void LockQueue()
96         {
97                 queue.Lock();
98         }
99         /** Unlock queue.
100          */
101         void UnlockQueue()
102         {
103                 queue.Unlock();
104         }
105         /** Unlock queue and wake up worker
106          */
107         void UnlockQueueWakeup()
108         {
109                 queue.Wakeup();
110                 queue.Unlock();
111         }
112         virtual void SetExitFlag()
113         {
114                 queue.Lock();
115                 Thread::SetExitFlag();
116                 queue.Wakeup();
117                 queue.Unlock();
118         }
119 };
120
121 class CoreExport SocketThread : public Thread
122 {
123         ThreadQueueData queue;
124         ThreadSignalData signal;
125  protected:
126         /** Waits for an enqueue operation to complete
127          * You MUST hold the queue lock when you call this.
128          * It will be unlocked while you wait, and will be relocked
129          * before the function returns
130          */
131         void WaitForQueue()
132         {
133                 queue.Wait();
134         }
135  public:
136         /** Notifies parent by making the SignalFD ready to read
137          * No requirements on locking
138          */
139         void NotifyParent();
140         SocketThread();
141         virtual ~SocketThread();
142         /** Lock queue.
143          */
144         void LockQueue()
145         {
146                 queue.Lock();
147         }
148         /** Unlock queue.
149          */
150         void UnlockQueue()
151         {
152                 queue.Unlock();
153         }
154         /** Unlock queue and send wakeup to worker
155          */
156         void UnlockQueueWakeup()
157         {
158                 queue.Wakeup();
159                 queue.Unlock();
160         }
161         virtual void SetExitFlag()
162         {
163                 queue.Lock();
164                 Thread::SetExitFlag();
165                 queue.Wakeup();
166                 queue.Unlock();
167         }
168
169         /**
170          * Called in the context of the parent thread after a notification
171          * has passed through the socket
172          */
173         virtual void OnNotify() = 0;
174 };
175
176 #endif
177