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