PageRenderTime 55ms CodeModel.GetById 8ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 1ms

/synch/thread.d

http://github.com/wilkie/djehuty
D | 297 lines | 202 code | 69 blank | 26 comment | 17 complexity | c34cb2f64ba99c8374ef220c1cee74fe MD5 | raw file
  1module synch.thread;
  2
  3import gui.window;
  4
  5// Awww... my only runtime dependency
  6version(Tango) {
  7	import Tango = tango.core.Thread;
  8}
  9else {
 10	import Phobos = std.thread;
 11}
 12
 13import platform.vars.thread;
 14
 15import scaffold.thread;
 16
 17// access to exception handler
 18import analyzing.debugger;
 19
 20// Access to the threads array
 21import core.main;
 22import core.system;
 23
 24import io.console;
 25
 26// Section: Core/Synchronization
 27
 28// Description: This class represents a thread.  You can create and override the call function to use, or use a delegate to specify an external function to call.
 29class Thread {
 30
 31	// Description: Will create a normal thread that does not have any external callback functions.
 32	this() {
 33		stdThread = new overrideThread();
 34		stdThread.thread = this;
 35
 36		startTime = time = System.time;
 37	}
 38
 39	// Description: Will create a thread using the given delegate as the callback function.
 40	this(void delegate(bool) callback) {
 41		_thread_callback = callback;
 42		_thread_f_callback = null;
 43
 44		stdThread = new overrideThread();
 45		stdThread.thread = this;
 46
 47		startTime = time = System.time;
 48	}
 49
 50	// Description: Will create a thread using the given function as the callback function.
 51	this(void function(bool) callback) {
 52		_thread_f_callback = callback;
 53		_thread_callback = null;
 54
 55		stdThread = new overrideThread();
 56		stdThread.thread = this;
 57	}
 58
 59	~this() {
 60		stop();
 61	}
 62
 63	// the common function for the thread
 64
 65	// Description: This will be called upon execution of the thread.  Normally, it will call the delegate, but if overriden, you can provide a function within the class to use as the execution space.
 66	void run() {
 67		if (_thread_callback !is null) {
 68			_thread_callback(false);
 69		}
 70		else if (_thread_f_callback !is null) {
 71			_thread_f_callback(false);
 72		}
 73
 74		_inited = false;
 75	}
 76
 77	// Description: This will allow an arbitrary member function to be used as the execution space.
 78	// callback: An address to a member function or a delegate literal.
 79	void callback(void delegate(bool) callback) {
 80		_thread_callback = callback;
 81		_thread_f_callback = null;
 82	}
 83
 84	// Description: This will allow an arbitrary function to be used as the execution space.
 85	// callback: An address to a function or a function literal.
 86	void callback(void function(bool) callback) {
 87		_thread_f_callback = callback;
 88		_thread_callback = null;
 89	}
 90
 91	// Description: This function will tell whether or not the current thread being executed is the thread created via this class.
 92	// Returns: Will return true when this thread is the current thread executing and false otherwise.
 93	bool isCurrentThread() {
 94		if (_inited) {
 95			return this is this.current(); //return ThreadIsCurrent(_pfvars);
 96		}
 97
 98		return false;
 99	}
100
101	// Description: This function will yield the thread for a certain amount of time.
102	// milliseconds: The number of milliseconds to yield.
103	void sleep(ulong milliseconds) {
104		// we are given a long for length, windows only has an int function
105		if (_inited) {
106			ThreadSleep(_pfvars, milliseconds);
107		}
108	}
109
110	// Description: This function will start the thread and call the threadProc() function, which will in turn execute an external delegate if provided.
111	void start() {
112		if (!_inited) {
113			RegisterThread(this);
114			//ThreadStart(_pfvars, this);
115
116			startTime = time = System.time;
117
118			if (stdThread is null) {
119				stdThread = new overrideThread();
120			}
121
122			_inited = true;
123			stdThread.start();
124		}
125	}
126
127	// Description: This function will stop the thread prematurely.
128	void stop() {
129		if (_inited) {
130			//ThreadStop(_pfvars);
131			stdThread = null;
132			UnregisterThread(this);
133		}
134		_inited = false;
135	}
136
137	void pleaseStop() {
138		if (_thread_callback !is null) {
139			_thread_callback(true);
140		}
141		else if (_thread_f_callback !is null) {
142			_thread_f_callback(true);
143		}
144	}
145
146	long getElapsed() {
147		return System.time - time;
148	}
149
150	long getDelta() {
151		long oldTime = time;
152		time = System.time;
153
154		return time - oldTime;
155	}
156
157	static Thread current() {
158		Thread ret;
159
160		version(LDC) {
161			if (Tango.Thread.getThis() in threadById) {
162				ret = threadById[Tango.Thread.getThis()];
163			}
164		}
165		else {
166			if (Phobos.Thread.getThis() in threadById) {
167				ret = threadById[Phobos.Thread.getThis()];
168			}
169		}
170
171		if (ret is null) {
172		}
173
174		return ret;
175	}
176
177protected:
178
179	void delegate (bool) _thread_callback = null;
180	void function (bool) _thread_f_callback = null;
181
182	int _threadProc() {
183		run();
184
185		stdThread = null;
186
187		return 0;
188	}
189
190	bool _inited;
191
192	long startTime;
193	long time;
194
195	Window wnd;
196
197	ThreadPlatformVars _pfvars;
198
199	overrideThread stdThread;
200
201	version(GNU)
202	{
203	}
204	version(LDC)
205	{
206		alias Tango.Thread RuntimeThread;
207		class overrideThread : Tango.Thread
208		{
209			Thread thread;
210			RuntimeThread runtimeThread;
211
212			this() {
213				super(&run);
214			}
215
216			void run()
217			{
218				threadById[Tango.Thread.getThis()] = thread;
219
220				try {
221					thread.run();
222				}
223				catch (Object o) {
224					// Catch any unhandled exceptions
225					Debugger.raiseException(cast(Exception)o, thread.wnd, thread);
226				}
227
228				stdThread = null;
229
230				UnregisterThread(thread);
231
232				return;
233			}
234		}
235	}
236	else
237	{
238		alias Phobos.Thread RuntimeThread;
239		class overrideThread
240		{
241			Thread thread;
242			RuntimeThread runtimeThread;
243
244			this() {
245				runtimeThread = new Phobos.Thread(&run);
246			}
247
248			void start() {
249				runtimeThread.start();
250			}
251
252			int run() {
253				threadById[Phobos.Thread.getThis()] = thread;
254
255				try {
256					thread.run();
257				}
258				catch (Object o) {
259					// Catch any unhandled exceptions
260					Debugger.raiseException(cast(Exception)o, thread.wnd, thread);
261				}
262
263				stdThread = null;
264
265				UnregisterThread(thread);
266
267				return 0;
268			}
269		}
270	}
271
272	static Thread[RuntimeThread] threadById;
273}
274
275void ThreadModuleInit() {
276
277	// create a Thread for the main thread
278	Thread mainThread = new Thread();
279	mainThread._inited = true;
280
281	version(Tango) {
282		mainThread.stdThread.runtimeThread = Tango.Thread.getThis();
283	}
284	else {
285		mainThread.stdThread.runtimeThread = Phobos.Thread.getThis();
286	}
287
288	Thread.threadById[mainThread.stdThread.runtimeThread] = mainThread;
289}
290
291void ThreadUninit(ref Thread t) {
292	t._inited = false;
293}
294
295void ThreadSetWindow(ref Thread t, Window w) {
296	t.wnd = w;
297}