summaryrefslogtreecommitdiff
path: root/include/threadengines/threadengine_pthread.h
blob: 6124f4cf91cf551e54541516d7a8b584778de7fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*       +------------------------------------+
 *       | Inspire Internet Relay Chat Daemon |
 *       +------------------------------------+
 *
 *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
 * See: http://wiki.inspircd.org/Credits
 *
 * This program is free but copyrighted software; see
 *            the file COPYING for details.
 *
 * ---------------------------------------------------
 */

#ifndef __THREADENGINE_PTHREAD__
#define __THREADENGINE_PTHREAD__

#include <pthread.h>
#include "typedefs.h"

/** The ThreadEngine class has the responsibility of initialising
 * Thread derived classes. It does this by creating operating system
 * level threads which are then associated with the class transparently.
 * This allows Thread classes to be derived without needing to know how
 * the OS implements threads. You should ensure that any sections of code
 * that use threads are threadsafe and do not interact with any other
 * parts of the code which are NOT known threadsafe! If you really MUST
 * access non-threadsafe code from a Thread, use the Mutex class to wrap
 * access to the code carefully.
 */
class CoreExport ThreadEngine
{
 public:

	/** Constructor.
	 * @param Instance Creator object
	 */
	ThreadEngine();

	/** Destructor
	 */
	virtual ~ThreadEngine();

	/** Create a new thread. This takes an already allocated
	 * Thread* pointer and initializes it to use this threading
	 * engine. On failure, this function may throw a CoreException.
	 * @param thread_to_init Pointer to a newly allocated Thread
	 * derived object.
	 */
	void Start(Thread* thread_to_init);

	/** Returns the thread engine's name for display purposes
	 * @return The thread engine name
	 */
	const std::string GetName()
	{
		return "posix-thread";
	}
};

class CoreExport ThreadData
{
 public:
	pthread_t pthread_id;
	void FreeThread(Thread* toFree);
};

/** The Mutex class represents a mutex, which can be used to keep threads
 * properly synchronised. Use mutexes sparingly, as they are a good source
 * of thread deadlocks etc, and should be avoided except where absolutely
 * neccessary. Note that the internal behaviour of the mutex varies from OS
 * to OS depending on the thread engine, for example in windows a Mutex
 * in InspIRCd uses critical sections, as they are faster and simpler to
 * manage.
 */
class CoreExport Mutex
{
 private:
	pthread_mutex_t putex;
 public:
	/** Constructor.
	 */
	Mutex()
	{
		pthread_mutex_init(&putex, NULL);
	}
	/** Enter/enable the mutex lock.
	 */
	void Lock()
	{
		pthread_mutex_lock(&putex);
	}
	/** Leave/disable the mutex lock.
	 */
	void Unlock()
	{
		pthread_mutex_unlock(&putex);
	}
	/** Destructor
	 */
	~Mutex()
	{
		pthread_mutex_destroy(&putex);
	}
};

class ThreadQueueData
{
	pthread_mutex_t mutex;
	pthread_cond_t cond;
 public:
	ThreadQueueData()
	{
		pthread_mutex_init(&mutex, NULL);
		pthread_cond_init(&cond, NULL);
	}

	~ThreadQueueData()
	{
		pthread_mutex_destroy(&mutex);
		pthread_cond_destroy(&cond);
	}

	void Lock()
	{
		pthread_mutex_lock(&mutex);
	}

	void Unlock()
	{
		pthread_mutex_unlock(&mutex);
	}

	void Wakeup()
	{
		pthread_cond_signal(&cond);
	}

	void Wait()
	{
		pthread_cond_wait(&cond, &mutex);
	}
};

class ThreadSignalSocket;
class ThreadSignalData
{
 public:
	ThreadSignalSocket* sock;
};


#endif