summaryrefslogtreecommitdiff
path: root/include/threadengine.h
blob: 9c87f83b267fadf58c442e7a06c97724b9f9b63e (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
/*       +------------------------------------+
 *       | Inspire Internet Relay Chat Daemon |
 *       +------------------------------------+
 *
 *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
 * See: http://www.inspircd.org/wiki/index.php/Credits
 *
 * This program is free but copyrighted software; see
 *            the file COPYING for details.
 *
 * ---------------------------------------------------
 */

#ifndef __THREADENGINE__
#define __THREADENGINE__

#include <vector>
#include <string>
#include <map>
#include "inspircd_config.h"
#include "base.h"

class InspIRCd;
class Thread;

/** 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!
 */
class CoreExport ThreadEngine : public Extensible
{
 protected:

	 /** Creator instance
	  */
	 InspIRCd* ServerInstance;
	 /** New Thread being created.
	  */
	 Thread* NewThread;

 public:

	/** Constructor
	 */
	ThreadEngine(InspIRCd* Instance);

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

	/** Enable or disable system-wide mutex for threading.
	 * This MUST be called when you deal with ANYTHING that
	 * isnt known thread-safe, this INCLUDES STL!
	 * Remember that if you toggle the mutex you MUST UNSET
	 * IT LATER otherwise the program will DEADLOCK!
	 */
	virtual bool Mutex(bool enable) = 0;

	/** Run the newly created thread
	 */
	virtual void Run() = 0;

	/** 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.
	 */
	virtual void Create(Thread* thread_to_init) = 0;

	/** This is called by the default destructor of the Thread
	 * class to ensure that the thread engine which created the thread
	 * is responsible for destroying it.
	 */
	virtual void FreeThread(Thread* thread) = 0;

	virtual const std::string GetName()
	{
		return "<pure-virtual>";
	}
};

class CoreExport Mutex : public Extensible
{
 protected:
	InspIRCd* ServerInstance;
 public:
	Mutex(InspIRCd* Instance);
	virtual void Enable(bool enable) = 0;
	void Lock() { Enable(true); }
	void Unlock() { Enable(false); }
	~Mutex() { }
};

/** Derive from this class to implement your own threaded sections of
 * code.
 */
class CoreExport Thread : public Extensible
{
 private:
	bool ExitFlag;
 public:

	/** Creator thread engine
	 */
	ThreadEngine* Creator;

	/** Set Creator to NULL at this point
	 */
	Thread() : ExitFlag(false), Creator(NULL)
	{
	}

	/** If this thread has a Creator set, call it to
	 * free the thread
	 */
	virtual ~Thread()
	{
		if (Creator)
			Creator->FreeThread(this);
	}

	/** Override this method to put your actual
	 * threaded code here
	 */
	virtual void Run() = 0;

	void SetExitFlag()
	{
		ExitFlag = true;
	}

	void ClearExitFlag()
	{
		ExitFlag = false;
	}

	bool GetExitFlag()
	{
		return ExitFlag;
	}
};



#endif