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