Browse code

Use std::thread in place of the Windows API CreateThread.

Naram Qashat authored on 2021/04/07 21:52:53
Showing 2 changed files
... ...
@@ -9,10 +9,12 @@
9 9
  */
10 10
 
11 11
 #include <algorithm>
12
+#include <atomic>
12 13
 #include <bitset>
13 14
 #include <filesystem>
14 15
 #include <memory>
15 16
 #include <string>
17
+#include <thread>
16 18
 #include <vector>
17 19
 #include <cstddef>
18 20
 #include <cstdint>
... ...
@@ -102,13 +104,13 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::filesystem::path &path) : XSFPlayer(),
102 104
 	this->xSF.reset(new XSFFile(path, 8, 12));
103 105
 }
104 106
 
105
-static HANDLE soundViewThreadHandle = INVALID_HANDLE_VALUE;
106
-static bool killSoundViewThread;
107
+static std::unique_ptr<std::thread> soundViewThreadHandle;
108
+static std::atomic_bool killSoundViewThread;
107 109
 
108
-static DWORD WINAPI soundViewThread(void *b)
110
+static void soundViewThread(XSFPlayer_NCSF *player)
109 111
 {
110 112
 	auto xSFConfig_NCSF = static_cast<XSFConfig_NCSF *>(xSFConfig.get());
111
-	xSFConfig_NCSF->CallSoundView(static_cast<XSFPlayer_NCSF *>(b), xSFConfig->GetHInstance(), nullptr);
113
+	xSFConfig_NCSF->CallSoundView(player, xSFConfig->GetHInstance(), nullptr);
112 114
 	MSG msg;
113 115
 	while (!killSoundViewThread)
114 116
 	{
... ...
@@ -120,7 +122,6 @@ static DWORD WINAPI soundViewThread(void *b)
120 122
 		}
121 123
 	}
122 124
 	xSFConfig_NCSF->CloseSoundView();
123
-	return 0;
124 125
 }
125 126
 
126 127
 XSFPlayer_NCSF::~XSFPlayer_NCSF()
... ...
@@ -136,7 +137,7 @@ bool XSFPlayer_NCSF::Load()
136 137
 	if (this->useSoundViewDialog)
137 138
 	{
138 139
 		killSoundViewThread = false;
139
-		soundViewThreadHandle = CreateThread(nullptr, 0, soundViewThread, this, 0, nullptr);
140
+		soundViewThreadHandle.reset(new std::thread(soundViewThread, this));
140 141
 	}
141 142
 
142 143
 	PseudoFile file;
... ...
@@ -214,17 +215,9 @@ void XSFPlayer_NCSF::Terminate()
214 215
 {
215 216
 	this->player.Stop(true);
216 217
 
217
-	if (soundViewThreadHandle != INVALID_HANDLE_VALUE)
218
-	{
219
-		killSoundViewThread = true;
220
-		if (WaitForSingleObject(soundViewThreadHandle, 2000) == WAIT_TIMEOUT)
221
-		{
222
-			TerminateThread(soundViewThreadHandle, 0);
223
-			static_cast<XSFConfig_NCSF *>(xSFConfig.get())->CloseSoundView();
224
-		}
225
-		CloseHandle(soundViewThreadHandle);
226
-		soundViewThreadHandle = INVALID_HANDLE_VALUE;
227
-	}
218
+	killSoundViewThread = true;
219
+	soundViewThreadHandle->join();
220
+	soundViewThreadHandle.reset();
228 221
 }
229 222
 
230 223
 void XSFPlayer_NCSF::SetUseSoundViewDialog(bool newUseSoundViewDialog)
... ...
@@ -6,9 +6,11 @@
6 6
  */
7 7
 
8 8
 #include <algorithm>
9
+#include <atomic>
9 10
 #include <memory>
10 11
 #include <stdexcept>
11 12
 #include <string>
13
+#include <thread>
12 14
 #include <utility>
13 15
 #include <vector>
14 16
 #include <cstddef>
... ...
@@ -28,18 +30,18 @@ XSFFile *xSFFileInInfo = nullptr;
28 30
 static std::unique_ptr<XSFPlayer> xSFPlayer;
29 31
 std::unique_ptr<XSFConfig> xSFConfig;
30 32
 static bool paused;
31
-static int seek_needed;
33
+static std::atomic_int seek_needed;
32 34
 static double decode_pos_ms;
33
-static HANDLE thread_handle = INVALID_HANDLE_VALUE;
34
-static bool killThread = false;
35
+static std::unique_ptr<std::thread> thread_handle;
36
+static std::atomic_bool killThread;
35 37
 
36 38
 static const unsigned NumChannels = 2;
37 39
 static const unsigned BitsPerSample = 16;
38 40
 
39
-DWORD WINAPI playThread(void *b)
41
+void playThread()
40 42
 {
41 43
 	bool done = false;
42
-	while (!*static_cast<bool *>(b))
44
+	while (!killThread)
43 45
 	{
44 46
 		if (seek_needed != -1)
45 47
 		{
... ...
@@ -55,7 +57,7 @@ DWORD WINAPI playThread(void *b)
55 57
 			if (!inMod.outMod->IsPlaying())
56 58
 			{
57 59
 				PostMessage(inMod.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
58
-				return 0;
60
+				return;
59 61
 			}
60 62
 			Sleep(10);
61 63
 		}
... ...
@@ -77,7 +79,6 @@ DWORD WINAPI playThread(void *b)
77 79
 		else
78 80
 			Sleep(20);
79 81
 	}
80
-	return 0;
81 82
 }
82 83
 
83 84
 void config(HWND hwndParent)
... ...
@@ -198,7 +199,7 @@ int play(const in_char *fn)
198 199
 
199 200
 		xSFPlayer = std::move(tmpxSFPlayer);
200 201
 		killThread = false;
201
-		thread_handle = CreateThread(nullptr, 0, playThread, &killThread, 0, nullptr);
202
+		thread_handle.reset(new std::thread(playThread));
202 203
 		return 0;
203 204
 	}
204 205
 	catch (const std::exception &)
... ...
@@ -226,17 +227,9 @@ int isPaused()
226 227
 
227 228
 void stop()
228 229
 {
229
-	if (thread_handle != INVALID_HANDLE_VALUE)
230
-	{
231
-		killThread = true;
232
-		if (WaitForSingleObject(thread_handle, 2000) == WAIT_TIMEOUT)
233
-		{
234
-			MessageBoxW(inMod.hMainWindow, L"error asking thread to die!", L"error killing decode thread", 0);
235
-			TerminateThread(thread_handle, 0);
236
-		}
237
-		CloseHandle(thread_handle);
238
-		thread_handle = INVALID_HANDLE_VALUE;
239
-	}
230
+	killThread = true;
231
+	thread_handle->join();
232
+	thread_handle.reset();
240 233
 	inMod.outMod->Close();
241 234
 	inMod.SAVSADeInit();
242 235
 	xSFPlayer.reset();