1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef AGS_ENGINE_UTIL_THREAD_WINDOWS_H
24 #define AGS_ENGINE_UTIL_THREAD_WINDOWS_H
25 
26 namespace AGS3 {
27 namespace AGS {
28 namespace Engine {
29 
30 
31 class WindowsThread : public BaseThread {
32 public:
WindowsThread()33 	WindowsThread() {
34 		_thread = NULL;
35 		_entry = NULL;
36 		_running = false;
37 		_looping = false;
38 	}
39 
~WindowsThread()40 	~WindowsThread() {
41 		Stop();
42 	}
43 
Create(AGSThreadEntry entryPoint,bool looping)44 	inline bool Create(AGSThreadEntry entryPoint, bool looping) {
45 		_looping = looping;
46 		_entry = entryPoint;
47 		_thread = CreateThread(NULL, 0, _thread_start, this, CREATE_SUSPENDED, NULL);
48 
49 		return (_thread != NULL);
50 	}
51 
Start()52 	inline bool Start() {
53 		if ((_thread != NULL) && (!_running)) {
54 			DWORD result = ResumeThread(_thread);
55 
56 			_running = (result != (DWORD) - 1);
57 			return _running;
58 		} else {
59 			return false;
60 		}
61 	}
62 
Stop()63 	bool Stop() {
64 		if ((_thread != NULL) && (_running)) {
65 			if (_looping) {
66 				_looping = false;
67 				WaitForSingleObject(_thread, INFINITE);
68 			}
69 
70 			CloseHandle(_thread);
71 
72 			_running = false;
73 			_thread = NULL;
74 			return true;
75 		} else {
76 			return false;
77 		}
78 	}
79 
80 private:
81 	HANDLE _thread;
82 	bool   _running;
83 	bool   _looping;
84 
85 	AGSThreadEntry _entry;
86 
_thread_start(LPVOID lpParam)87 	static DWORD __stdcall _thread_start(LPVOID lpParam) {
88 		AGSThreadEntry entry = ((WindowsThread *)lpParam)->_entry;
89 		bool *looping = &((WindowsThread *)lpParam)->_looping;
90 
91 		do {
92 			entry();
93 		} while (*looping);
94 
95 		return 0;
96 	}
97 };
98 
99 
100 typedef WindowsThread Thread;
101 
102 
103 } // namespace Engine
104 } // namespace AGS
105 } // namespace AGS3
106 
107 #endif
108