瀏覽代碼

Make audio thread control flags safe

Pedro J. Estébanez 3 年之前
父節點
當前提交
c92ceca5ce

+ 11 - 14
drivers/alsa/audio_driver_alsa.cpp

@@ -168,9 +168,8 @@ Error AudioDriverALSA::init() {
 		return ERR_CANT_OPEN;
 		return ERR_CANT_OPEN;
 	}
 	}
 
 
-	active = false;
-	thread_exited = false;
-	exit_thread = false;
+	active.clear();
+	exit_thread.clear();
 
 
 	Error err = init_device();
 	Error err = init_device();
 	if (err == OK) {
 	if (err == OK) {
@@ -183,11 +182,11 @@ Error AudioDriverALSA::init() {
 void AudioDriverALSA::thread_func(void *p_udata) {
 void AudioDriverALSA::thread_func(void *p_udata) {
 	AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
 	AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
 
 
-	while (!ad->exit_thread) {
+	while (!ad->exit_thread.is_set()) {
 		ad->lock();
 		ad->lock();
 		ad->start_counting_ticks();
 		ad->start_counting_ticks();
 
 
-		if (!ad->active) {
+		if (!ad->active.is_set()) {
 			for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
 			for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
 				ad->samples_out.write[i] = 0;
 				ad->samples_out.write[i] = 0;
 			}
 			}
@@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
 		int todo = ad->period_size;
 		int todo = ad->period_size;
 		int total = 0;
 		int total = 0;
 
 
-		while (todo && !ad->exit_thread) {
+		while (todo && !ad->exit_thread.is_set()) {
 			int16_t *src = (int16_t *)ad->samples_out.ptr();
 			int16_t *src = (int16_t *)ad->samples_out.ptr();
 			int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
 			int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
 
 
@@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
 				wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
 				wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
 				if (wrote < 0) {
 				if (wrote < 0) {
 					ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
 					ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
-					ad->active = false;
-					ad->exit_thread = true;
+					ad->active.clear();
+					ad->exit_thread.set();
 				}
 				}
 			}
 			}
 		}
 		}
@@ -241,8 +240,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
 
 
 				err = ad->init_device();
 				err = ad->init_device();
 				if (err != OK) {
 				if (err != OK) {
-					ad->active = false;
-					ad->exit_thread = true;
+					ad->active.clear();
+					ad->exit_thread.set();
 				}
 				}
 			}
 			}
 		}
 		}
@@ -250,12 +249,10 @@ void AudioDriverALSA::thread_func(void *p_udata) {
 		ad->stop_counting_ticks();
 		ad->stop_counting_ticks();
 		ad->unlock();
 		ad->unlock();
 	}
 	}
-
-	ad->thread_exited = true;
 }
 }
 
 
 void AudioDriverALSA::start() {
 void AudioDriverALSA::start() {
-	active = true;
+	active.set();
 }
 }
 
 
 int AudioDriverALSA::get_mix_rate() const {
 int AudioDriverALSA::get_mix_rate() const {
@@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() {
 }
 }
 
 
 void AudioDriverALSA::finish() {
 void AudioDriverALSA::finish() {
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	finish_device();
 	finish_device();

+ 3 - 3
drivers/alsa/audio_driver_alsa.h

@@ -35,6 +35,7 @@
 
 
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"
 
 
 #include "asound-so_wrap.h"
 #include "asound-so_wrap.h"
@@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver {
 	snd_pcm_uframes_t period_size;
 	snd_pcm_uframes_t period_size;
 	int channels;
 	int channels;
 
 
-	bool active;
-	bool thread_exited;
-	mutable bool exit_thread;
+	SafeFlag active;
+	SafeFlag exit_thread;
 
 
 public:
 public:
 	const char *get_name() const {
 	const char *get_name() const {

+ 4 - 4
drivers/alsamidi/midi_driver_alsamidi.cpp

@@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
 	int expected_size = 255;
 	int expected_size = 255;
 	int bytes = 0;
 	int bytes = 0;
 
 
-	while (!md->exit_thread) {
+	while (!md->exit_thread.is_set()) {
 		int ret;
 		int ret;
 
 
 		md->lock();
 		md->lock();
@@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() {
 	}
 	}
 	snd_device_name_free_hint(hints);
 	snd_device_name_free_hint(hints);
 
 
-	exit_thread = false;
+	exit_thread.clear();
 	thread.start(MIDIDriverALSAMidi::thread_func, this);
 	thread.start(MIDIDriverALSAMidi::thread_func, this);
 
 
 	return OK;
 	return OK;
 }
 }
 
 
 void MIDIDriverALSAMidi::close() {
 void MIDIDriverALSAMidi::close() {
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	for (int i = 0; i < connected_inputs.size(); i++) {
 	for (int i = 0; i < connected_inputs.size(); i++) {
@@ -193,7 +193,7 @@ PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
 }
 }
 
 
 MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
 MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
-	exit_thread = false;
+	exit_thread.clear();
 }
 }
 
 
 MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
 MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {

+ 2 - 1
drivers/alsamidi/midi_driver_alsamidi.h

@@ -36,6 +36,7 @@
 #include "core/os/midi_driver.h"
 #include "core/os/midi_driver.h"
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 #include "core/vector.h"
 #include "core/vector.h"
 
 
 #include "../alsa/asound-so_wrap.h"
 #include "../alsa/asound-so_wrap.h"
@@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
 
 
 	Vector<snd_rawmidi_t *> connected_inputs;
 	Vector<snd_rawmidi_t *> connected_inputs;
 
 
-	bool exit_thread;
+	SafeFlag exit_thread;
 
 
 	static void thread_func(void *p_udata);
 	static void thread_func(void *p_udata);
 
 

+ 12 - 18
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() {
 		return ERR_CANT_OPEN;
 		return ERR_CANT_OPEN;
 	}
 	}
 
 
-	active = false;
-	thread_exited = false;
-	exit_thread = false;
+	active.clear();
+	exit_thread.clear();
 
 
 	mix_rate = GLOBAL_GET("audio/mix_rate");
 	mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
@@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 	size_t avail_bytes = 0;
 	size_t avail_bytes = 0;
 	uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();
 	uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();
 
 
-	while (!ad->exit_thread) {
+	while (!ad->exit_thread.is_set()) {
 		size_t read_bytes = 0;
 		size_t read_bytes = 0;
 		size_t written_bytes = 0;
 		size_t written_bytes = 0;
 
 
@@ -394,7 +393,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 			int16_t *out_ptr = ad->samples_out.ptrw();
 			int16_t *out_ptr = ad->samples_out.ptrw();
 
 
-			if (!ad->active) {
+			if (!ad->active.is_set()) {
 				for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
 				for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
 					out_ptr[i] = 0;
 					out_ptr[i] = 0;
 				}
 				}
@@ -464,8 +463,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 				err = ad->init_device();
 				err = ad->init_device();
 				if (err != OK) {
 				if (err != OK) {
-					ad->active = false;
-					ad->exit_thread = true;
+					ad->active.clear();
+					ad->exit_thread.set();
 					break;
 					break;
 				}
 				}
 			}
 			}
@@ -503,8 +502,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 					Error err = ad->init_device();
 					Error err = ad->init_device();
 					if (err != OK) {
 					if (err != OK) {
 						ERR_PRINT("PulseAudio: init_device error");
 						ERR_PRINT("PulseAudio: init_device error");
-						ad->active = false;
-						ad->exit_thread = true;
+						ad->active.clear();
+						ad->exit_thread.set();
 						break;
 						break;
 					}
 					}
 
 
@@ -557,8 +556,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 
 
 					err = ad->capture_init_device();
 					err = ad->capture_init_device();
 					if (err != OK) {
 					if (err != OK) {
-						ad->active = false;
-						ad->exit_thread = true;
+						ad->active.clear();
+						ad->exit_thread.set();
 						break;
 						break;
 					}
 					}
 				}
 				}
@@ -573,12 +572,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
 			OS::get_singleton()->delay_usec(1000);
 			OS::get_singleton()->delay_usec(1000);
 		}
 		}
 	}
 	}
-
-	ad->thread_exited = true;
 }
 }
 
 
 void AudioDriverPulseAudio::start() {
 void AudioDriverPulseAudio::start() {
-	active = true;
+	active.set();
 }
 }
 
 
 int AudioDriverPulseAudio::get_mix_rate() const {
 int AudioDriverPulseAudio::get_mix_rate() const {
@@ -663,7 +660,7 @@ void AudioDriverPulseAudio::finish() {
 		return;
 		return;
 	}
 	}
 
 
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	finish_device();
 	finish_device();
@@ -840,9 +837,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() :
 		channels(0),
 		channels(0),
 		pa_ready(0),
 		pa_ready(0),
 		pa_status(0),
 		pa_status(0),
-		active(false),
-		thread_exited(false),
-		exit_thread(false),
 		latency(0) {
 		latency(0) {
 	samples_in.clear();
 	samples_in.clear();
 	samples_out.clear();
 	samples_out.clear();

+ 3 - 3
drivers/pulseaudio/audio_driver_pulseaudio.h

@@ -35,6 +35,7 @@
 
 
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"
 
 
 #include "pulse-so_wrap.h"
 #include "pulse-so_wrap.h"
@@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver {
 	Array pa_devices;
 	Array pa_devices;
 	Array pa_rec_devices;
 	Array pa_rec_devices;
 
 
-	bool active;
-	bool thread_exited;
-	mutable bool exit_thread;
+	SafeFlag active;
+	SafeFlag exit_thread;
 
 
 	float latency;
 	float latency;
 
 

+ 13 - 19
drivers/wasapi/audio_driver_wasapi.cpp

@@ -365,12 +365,12 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
 }
 }
 
 
 Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
 Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
-	if (p_device->active) {
+	if (p_device->active.is_set()) {
 		if (p_device->audio_client) {
 		if (p_device->audio_client) {
 			p_device->audio_client->Stop();
 			p_device->audio_client->Stop();
 		}
 		}
 
 
-		p_device->active = false;
+		p_device->active.clear();
 	}
 	}
 
 
 	SAFE_RELEASE(p_device->audio_client)
 	SAFE_RELEASE(p_device->audio_client)
@@ -396,8 +396,7 @@ Error AudioDriverWASAPI::init() {
 		ERR_PRINT("WASAPI: init_render_device error");
 		ERR_PRINT("WASAPI: init_render_device error");
 	}
 	}
 
 
-	exit_thread = false;
-	thread_exited = false;
+	exit_thread.clear();
 
 
 	thread.start(thread_func, this);
 	thread.start(thread_func, this);
 
 
@@ -543,7 +542,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 	uint32_t avail_frames = 0;
 	uint32_t avail_frames = 0;
 	uint32_t write_ofs = 0;
 	uint32_t write_ofs = 0;
 
 
-	while (!ad->exit_thread) {
+	while (!ad->exit_thread.is_set()) {
 		uint32_t read_frames = 0;
 		uint32_t read_frames = 0;
 		uint32_t written_frames = 0;
 		uint32_t written_frames = 0;
 
 
@@ -551,7 +550,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 			ad->lock();
 			ad->lock();
 			ad->start_counting_ticks();
 			ad->start_counting_ticks();
 
 
-			if (ad->audio_output.active) {
+			if (ad->audio_output.active.is_set()) {
 				ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
 				ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
 			} else {
 			} else {
 				for (int i = 0; i < ad->samples_in.size(); i++) {
 				for (int i = 0; i < ad->samples_in.size(); i++) {
@@ -617,7 +616,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 						}
 						}
 					} else {
 					} else {
 						ERR_PRINT("WASAPI: Get buffer error");
 						ERR_PRINT("WASAPI: Get buffer error");
-						ad->exit_thread = true;
+						ad->exit_thread.set();
 					}
 					}
 				}
 				}
 			} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
 			} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
@@ -666,7 +665,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 			write_ofs = 0;
 			write_ofs = 0;
 		}
 		}
 
 
-		if (ad->audio_input.active) {
+		if (ad->audio_input.active.is_set()) {
 			UINT32 packet_length = 0;
 			UINT32 packet_length = 0;
 			BYTE *data;
 			BYTE *data;
 			UINT32 num_frames_available;
 			UINT32 num_frames_available;
@@ -745,8 +744,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
 			OS::get_singleton()->delay_usec(1000);
 			OS::get_singleton()->delay_usec(1000);
 		}
 		}
 	}
 	}
-
-	ad->thread_exited = true;
 }
 }
 
 
 void AudioDriverWASAPI::start() {
 void AudioDriverWASAPI::start() {
@@ -755,7 +752,7 @@ void AudioDriverWASAPI::start() {
 		if (hr != S_OK) {
 		if (hr != S_OK) {
 			ERR_PRINT("WASAPI: Start failed");
 			ERR_PRINT("WASAPI: Start failed");
 		} else {
 		} else {
-			audio_output.active = true;
+			audio_output.active.set();
 		}
 		}
 	}
 	}
 }
 }
@@ -769,7 +766,7 @@ void AudioDriverWASAPI::unlock() {
 }
 }
 
 
 void AudioDriverWASAPI::finish() {
 void AudioDriverWASAPI::finish() {
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	finish_capture_device();
 	finish_capture_device();
@@ -783,19 +780,19 @@ Error AudioDriverWASAPI::capture_start() {
 		return err;
 		return err;
 	}
 	}
 
 
-	if (audio_input.active) {
+	if (audio_input.active.is_set()) {
 		return FAILED;
 		return FAILED;
 	}
 	}
 
 
 	audio_input.audio_client->Start();
 	audio_input.audio_client->Start();
-	audio_input.active = true;
+	audio_input.active.set();
 	return OK;
 	return OK;
 }
 }
 
 
 Error AudioDriverWASAPI::capture_stop() {
 Error AudioDriverWASAPI::capture_stop() {
-	if (audio_input.active) {
+	if (audio_input.active.is_set()) {
 		audio_input.audio_client->Stop();
 		audio_input.audio_client->Stop();
-		audio_input.active = false;
+		audio_input.active.clear();
 
 
 		return OK;
 		return OK;
 	}
 	}
@@ -827,9 +824,6 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
 	channels = 0;
 	channels = 0;
 	mix_rate = 0;
 	mix_rate = 0;
 	buffer_frames = 0;
 	buffer_frames = 0;
-
-	thread_exited = false;
-	exit_thread = false;
 }
 }
 
 
 #endif
 #endif

+ 3 - 4
drivers/wasapi/audio_driver_wasapi.h

@@ -35,6 +35,7 @@
 
 
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"
 
 
 #include <audioclient.h>
 #include <audioclient.h>
@@ -48,7 +49,7 @@ class AudioDriverWASAPI : public AudioDriver {
 		IAudioClient *audio_client;
 		IAudioClient *audio_client;
 		IAudioRenderClient *render_client;
 		IAudioRenderClient *render_client;
 		IAudioCaptureClient *capture_client;
 		IAudioCaptureClient *capture_client;
-		bool active;
+		SafeFlag active;
 
 
 		WORD format_tag;
 		WORD format_tag;
 		WORD bits_per_sample;
 		WORD bits_per_sample;
@@ -62,7 +63,6 @@ class AudioDriverWASAPI : public AudioDriver {
 				audio_client(NULL),
 				audio_client(NULL),
 				render_client(NULL),
 				render_client(NULL),
 				capture_client(NULL),
 				capture_client(NULL),
-				active(false),
 				format_tag(0),
 				format_tag(0),
 				bits_per_sample(0),
 				bits_per_sample(0),
 				channels(0),
 				channels(0),
@@ -84,8 +84,7 @@ class AudioDriverWASAPI : public AudioDriver {
 	int mix_rate;
 	int mix_rate;
 	int buffer_frames;
 	int buffer_frames;
 
 
-	bool thread_exited;
-	mutable bool exit_thread;
+	SafeFlag exit_thread;
 
 
 	static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
 	static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
 	static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
 	static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);

+ 8 - 9
drivers/xaudio2/audio_driver_xaudio2.cpp

@@ -38,9 +38,8 @@ const char *AudioDriverXAudio2::get_name() const {
 }
 }
 
 
 Error AudioDriverXAudio2::init() {
 Error AudioDriverXAudio2::init() {
-	active = false;
-	thread_exited = false;
-	exit_thread = false;
+	active.clear();
+	exit_thread.clear();
 	pcm_open = false;
 	pcm_open = false;
 	samples_in = NULL;
 	samples_in = NULL;
 
 
@@ -86,17 +85,19 @@ Error AudioDriverXAudio2::init() {
 void AudioDriverXAudio2::thread_func(void *p_udata) {
 void AudioDriverXAudio2::thread_func(void *p_udata) {
 	AudioDriverXAudio2 *ad = (AudioDriverXAudio2 *)p_udata;
 	AudioDriverXAudio2 *ad = (AudioDriverXAudio2 *)p_udata;
 
 
-	while (!ad->exit_thread) {
-		if (!ad->active) {
+	while (!ad->exit_thread.is_set()) {
+		if (!ad->active.is_set()) {
 			for (int i = 0; i < AUDIO_BUFFERS; i++) {
 			for (int i = 0; i < AUDIO_BUFFERS; i++) {
 				ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
 				ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
 			}
 			}
 
 
 		} else {
 		} else {
 			ad->lock();
 			ad->lock();
+			ad->start_counting_ticks();
 
 
 			ad->audio_server_process(ad->buffer_size, ad->samples_in);
 			ad->audio_server_process(ad->buffer_size, ad->samples_in);
 
 
+			ad->stop_counting_ticks();
 			ad->unlock();
 			ad->unlock();
 
 
 			for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
 			for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
@@ -117,12 +118,10 @@ void AudioDriverXAudio2::thread_func(void *p_udata) {
 			}
 			}
 		}
 		}
 	}
 	}
-
-	ad->thread_exited = true;
 }
 }
 
 
 void AudioDriverXAudio2::start() {
 void AudioDriverXAudio2::start() {
-	active = true;
+	active.set();
 	HRESULT hr = source_voice->Start(0);
 	HRESULT hr = source_voice->Start(0);
 	ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
 	ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
 }
 }
@@ -156,7 +155,7 @@ void AudioDriverXAudio2::finish() {
 	if (!thread.is_started())
 	if (!thread.is_started())
 		return;
 		return;
 
 
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	if (source_voice) {
 	if (source_voice) {

+ 3 - 3
drivers/xaudio2/audio_driver_xaudio2.h

@@ -33,6 +33,7 @@
 
 
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 #include "servers/audio_server.h"
 #include "servers/audio_server.h"
 
 
 #include <mmsystem.h>
 #include <mmsystem.h>
@@ -77,9 +78,8 @@ class AudioDriverXAudio2 : public AudioDriver {
 
 
 	int channels;
 	int channels;
 
 
-	bool active;
-	bool thread_exited;
-	mutable bool exit_thread;
+	SafeFlag active;
+	SafeFlag exit_thread;
 	bool pcm_open;
 	bool pcm_open;
 
 
 	WAVEFORMATEX wave_format;
 	WAVEFORMATEX wave_format;

+ 8 - 9
servers/audio/audio_driver_dummy.cpp

@@ -34,9 +34,8 @@
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 
 
 Error AudioDriverDummy::init() {
 Error AudioDriverDummy::init() {
-	active = false;
-	thread_exited = false;
-	exit_thread = false;
+	active.clear();
+	exit_thread.clear();
 	samples_in = nullptr;
 	samples_in = nullptr;
 
 
 	mix_rate = GLOBAL_GET("audio/mix_rate");
 	mix_rate = GLOBAL_GET("audio/mix_rate");
@@ -58,23 +57,23 @@ void AudioDriverDummy::thread_func(void *p_udata) {
 
 
 	uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
 	uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
 
 
-	while (!ad->exit_thread) {
-		if (ad->active) {
+	while (!ad->exit_thread.is_set()) {
+		if (ad->active.is_set()) {
 			ad->lock();
 			ad->lock();
+			ad->start_counting_ticks();
 
 
 			ad->audio_server_process(ad->buffer_frames, ad->samples_in);
 			ad->audio_server_process(ad->buffer_frames, ad->samples_in);
 
 
+			ad->stop_counting_ticks();
 			ad->unlock();
 			ad->unlock();
 		};
 		};
 
 
 		OS::get_singleton()->delay_usec(usdelay);
 		OS::get_singleton()->delay_usec(usdelay);
 	};
 	};
-
-	ad->thread_exited = true;
 };
 };
 
 
 void AudioDriverDummy::start() {
 void AudioDriverDummy::start() {
-	active = true;
+	active.set();
 };
 };
 
 
 int AudioDriverDummy::get_mix_rate() const {
 int AudioDriverDummy::get_mix_rate() const {
@@ -94,7 +93,7 @@ void AudioDriverDummy::unlock() {
 };
 };
 
 
 void AudioDriverDummy::finish() {
 void AudioDriverDummy::finish() {
-	exit_thread = true;
+	exit_thread.set();
 	thread.wait_to_finish();
 	thread.wait_to_finish();
 
 
 	if (samples_in) {
 	if (samples_in) {

+ 3 - 3
servers/audio/audio_driver_dummy.h

@@ -35,6 +35,7 @@
 
 
 #include "core/os/mutex.h"
 #include "core/os/mutex.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
+#include "core/safe_refcount.h"
 
 
 class AudioDriverDummy : public AudioDriver {
 class AudioDriverDummy : public AudioDriver {
 	Thread thread;
 	Thread thread;
@@ -50,9 +51,8 @@ class AudioDriverDummy : public AudioDriver {
 
 
 	int channels;
 	int channels;
 
 
-	bool active;
-	bool thread_exited;
-	mutable bool exit_thread;
+	SafeFlag active;
+	SafeFlag exit_thread;
 
 
 public:
 public:
 	const char *get_name() const {
 	const char *get_name() const {