]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/threadengines/threadengine_win32.h
Update copyright headers.
[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 "config.h"
28 #include "base.h"
29
30 class Thread;
31
32 /** The ThreadEngine class has the responsibility of initialising
33  * Thread derived classes. It does this by creating operating system
34  * level threads which are then associated with the class transparently.
35  * This allows Thread classes to be derived without needing to know how
36  * the OS implements threads. You should ensure that any sections of code
37  * that use threads are threadsafe and do not interact with any other
38  * parts of the code which are NOT known threadsafe! If you really MUST
39  * access non-threadsafe code from a Thread, use the Mutex class to wrap
40  * access to the code carefully.
41  */
42 class CoreExport ThreadEngine
43 {
44  public:
45         /** Per-thread state, present in each Thread object, managed by the ThreadEngine
46          */
47         struct ThreadState
48         {
49                 HANDLE handle;
50         };
51
52         static DWORD WINAPI Entry(void* parameter);
53
54         /** Create a new thread. This takes an already allocated
55           * Thread* pointer and initializes it to use this threading
56           * engine. On failure, this function may throw a CoreException.
57           * @param thread_to_init Pointer to a newly allocated Thread
58           * derived object.
59           */
60         void Start(Thread* thread_to_init);
61
62         /** Stop a thread gracefully.
63          * First, this function asks the thread to terminate by calling Thread::SetExitFlag().
64          * Next, it waits until the thread terminates (on the operating system level). Finally,
65          * all OS-level resources associated with the thread are released. The Thread instance
66          * passed to the function is NOT freed.
67          * When this function returns, the thread is stopped and you can destroy it or restart it
68          * at a later point.
69          * Stopping a thread that is not running is a bug.
70          * @param thread The thread to stop.
71          */
72         void Stop(Thread* thread);
73 };
74
75 /** The Mutex class represents a mutex, which can be used to keep threads
76  * properly synchronised. Use mutexes sparingly, as they are a good source
77  * of thread deadlocks etc, and should be avoided except where absolutely
78  * neccessary. Note that the internal behaviour of the mutex varies from OS
79  * to OS depending on the thread engine, for example in windows a Mutex
80  * in InspIRCd uses critical sections, as they are faster and simpler to
81  * manage.
82  */
83 class CoreExport Mutex
84 {
85  private:
86         CRITICAL_SECTION wutex;
87  public:
88         Mutex()
89         {
90                 InitializeCriticalSection(&wutex);
91         }
92         void Lock()
93         {
94                 EnterCriticalSection(&wutex);
95         }
96         void Unlock()
97         {
98                 LeaveCriticalSection(&wutex);
99         }
100         ~Mutex()
101         {
102                 DeleteCriticalSection(&wutex);
103         }
104 };
105
106 class ThreadQueueData : public Mutex
107 {
108         HANDLE event;
109  public:
110         ThreadQueueData()
111         {
112                 event = CreateEvent(NULL, false, false, NULL);
113                 if (event == NULL)
114                         throw CoreException("CreateEvent() failed in ThreadQueueData::ThreadQueueData()!");
115         }
116
117         ~ThreadQueueData()
118         {
119                 CloseHandle(event);
120         }
121
122         void Wakeup()
123         {
124                 PulseEvent(event);
125         }
126
127         void Wait()
128         {
129                 Unlock();
130                 WaitForSingleObject(event, INFINITE);
131                 Lock();
132         }
133 };
134
135 class ThreadSignalData
136 {
137  public:
138         int connFD;
139         ThreadSignalData()
140         {
141                 connFD = -1;
142         }
143 };