]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengine.h
Move and rename class ThreadData to ThreadEngine::ThreadState
[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         /* If the thread is running, you MUST join BEFORE deletion */
64         virtual ~Thread();
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         virtual void SetExitFlag()
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         virtual void SetExitFlag()
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 };