]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengines/threadengine_win32.h
Fix a bunch of weird indentation and spacing issues.
[user/henk/code/inspircd.git] / include / threadengines / threadengine_win32.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
5  *   Copyright (C) 2013 Sadie Powell <sadie@witchery.services>
6  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
7  *   Copyright (C) 2012 ChrisTX <xpipe@hotmail.de>
8  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
9  *   Copyright (C) 2008-2010 Craig Edwards <brain@inspircd.org>
10  *
11  * This file is part of InspIRCd.  InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24
25 #pragma once
26
27 #include "base.h"
28
29 class Thread;
30
31 /** The ThreadEngine class has the responsibility of initialising
32  * Thread derived classes. It does this by creating operating system
33  * level threads which are then associated with the class transparently.
34  * This allows Thread classes to be derived without needing to know how
35  * the OS implements threads. You should ensure that any sections of code
36  * that use threads are threadsafe and do not interact with any other
37  * parts of the code which are NOT known threadsafe! If you really MUST
38  * access non-threadsafe code from a Thread, use the Mutex class to wrap
39  * access to the code carefully.
40  */
41 class CoreExport ThreadEngine
42 {
43  public:
44         /** Per-thread state, present in each Thread object, managed by the ThreadEngine
45          */
46         struct ThreadState
47         {
48                 HANDLE handle;
49         };
50
51         static DWORD WINAPI Entry(void* parameter);
52
53         /** Create a new thread. This takes an already allocated
54          * Thread* pointer and initializes it to use this threading
55          * engine. On failure, this function may throw a CoreException.
56          * @param thread_to_init Pointer to a newly allocated Thread
57          * derived object.
58          */
59         void Start(Thread* thread_to_init);
60
61         /** Stop a thread gracefully.
62          * First, this function asks the thread to terminate by calling Thread::SetExitFlag().
63          * Next, it waits until the thread terminates (on the operating system level). Finally,
64          * all OS-level resources associated with the thread are released. The Thread instance
65          * passed to the function is NOT freed.
66          * When this function returns, the thread is stopped and you can destroy it or restart it
67          * at a later point.
68          * Stopping a thread that is not running is a bug.
69          * @param thread The thread to stop.
70          */
71         void Stop(Thread* thread);
72 };
73
74 /** The Mutex class represents a mutex, which can be used to keep threads
75  * properly synchronised. Use mutexes sparingly, as they are a good source
76  * of thread deadlocks etc, and should be avoided except where absolutely
77  * necessary. Note that the internal behaviour of the mutex varies from OS
78  * to OS depending on the thread engine, for example in windows a Mutex
79  * in InspIRCd uses critical sections, as they are faster and simpler to
80  * manage.
81  */
82 class CoreExport Mutex
83 {
84  private:
85         CRITICAL_SECTION wutex;
86  public:
87         Mutex()
88         {
89                 InitializeCriticalSection(&wutex);
90         }
91         void Lock()
92         {
93                 EnterCriticalSection(&wutex);
94         }
95         void Unlock()
96         {
97                 LeaveCriticalSection(&wutex);
98         }
99         ~Mutex()
100         {
101                 DeleteCriticalSection(&wutex);
102         }
103 };
104
105 class ThreadQueueData : public Mutex
106 {
107         HANDLE event;
108  public:
109         ThreadQueueData()
110         {
111                 event = CreateEvent(NULL, false, false, NULL);
112                 if (event == NULL)
113                         throw CoreException("CreateEvent() failed in ThreadQueueData::ThreadQueueData()!");
114         }
115
116         ~ThreadQueueData()
117         {
118                 CloseHandle(event);
119         }
120
121         void Wakeup()
122         {
123                 PulseEvent(event);
124         }
125
126         void Wait()
127         {
128                 Unlock();
129                 WaitForSingleObject(event, INFINITE);
130                 Lock();
131         }
132 };
133
134 class ThreadSignalData
135 {
136  public:
137         int connFD;
138         ThreadSignalData()
139         {
140                 connFD = -1;
141         }
142 };