Skip to content

Commit a86da2e

Browse files
authored
Merge pull request #64608 from RandomShaper/safe_audio_threading_3.x
2 parents 59402ff + c92ceca commit a86da2e

12 files changed

+73
-90
lines changed

drivers/alsa/audio_driver_alsa.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,8 @@ Error AudioDriverALSA::init() {
168168
return ERR_CANT_OPEN;
169169
}
170170

171-
active = false;
172-
thread_exited = false;
173-
exit_thread = false;
171+
active.clear();
172+
exit_thread.clear();
174173

175174
Error err = init_device();
176175
if (err == OK) {
@@ -183,11 +182,11 @@ Error AudioDriverALSA::init() {
183182
void AudioDriverALSA::thread_func(void *p_udata) {
184183
AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
185184

186-
while (!ad->exit_thread) {
185+
while (!ad->exit_thread.is_set()) {
187186
ad->lock();
188187
ad->start_counting_ticks();
189188

190-
if (!ad->active) {
189+
if (!ad->active.is_set()) {
191190
for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
192191
ad->samples_out.write[i] = 0;
193192
}
@@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
203202
int todo = ad->period_size;
204203
int total = 0;
205204

206-
while (todo && !ad->exit_thread) {
205+
while (todo && !ad->exit_thread.is_set()) {
207206
int16_t *src = (int16_t *)ad->samples_out.ptr();
208207
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
209208

@@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
222221
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
223222
if (wrote < 0) {
224223
ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
225-
ad->active = false;
226-
ad->exit_thread = true;
224+
ad->active.clear();
225+
ad->exit_thread.set();
227226
}
228227
}
229228
}
@@ -241,21 +240,19 @@ void AudioDriverALSA::thread_func(void *p_udata) {
241240

242241
err = ad->init_device();
243242
if (err != OK) {
244-
ad->active = false;
245-
ad->exit_thread = true;
243+
ad->active.clear();
244+
ad->exit_thread.set();
246245
}
247246
}
248247
}
249248

250249
ad->stop_counting_ticks();
251250
ad->unlock();
252251
}
253-
254-
ad->thread_exited = true;
255252
}
256253

257254
void AudioDriverALSA::start() {
258-
active = true;
255+
active.set();
259256
}
260257

261258
int AudioDriverALSA::get_mix_rate() const {
@@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() {
327324
}
328325

329326
void AudioDriverALSA::finish() {
330-
exit_thread = true;
327+
exit_thread.set();
331328
thread.wait_to_finish();
332329

333330
finish_device();

drivers/alsa/audio_driver_alsa.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "core/os/mutex.h"
3737
#include "core/os/thread.h"
38+
#include "core/safe_refcount.h"
3839
#include "servers/audio_server.h"
3940

4041
#include "asound-so_wrap.h"
@@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver {
6465
snd_pcm_uframes_t period_size;
6566
int channels;
6667

67-
bool active;
68-
bool thread_exited;
69-
mutable bool exit_thread;
68+
SafeFlag active;
69+
SafeFlag exit_thread;
7070

7171
public:
7272
const char *get_name() const {

drivers/alsamidi/midi_driver_alsamidi.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
7979
int expected_size = 255;
8080
int bytes = 0;
8181

82-
while (!md->exit_thread) {
82+
while (!md->exit_thread.is_set()) {
8383
int ret;
8484

8585
md->lock();
@@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() {
149149
}
150150
snd_device_name_free_hint(hints);
151151

152-
exit_thread = false;
152+
exit_thread.clear();
153153
thread.start(MIDIDriverALSAMidi::thread_func, this);
154154

155155
return OK;
156156
}
157157

158158
void MIDIDriverALSAMidi::close() {
159-
exit_thread = true;
159+
exit_thread.set();
160160
thread.wait_to_finish();
161161

162162
for (int i = 0; i < connected_inputs.size(); i++) {
@@ -193,7 +193,7 @@ PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
193193
}
194194

195195
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
196-
exit_thread = false;
196+
exit_thread.clear();
197197
}
198198

199199
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {

drivers/alsamidi/midi_driver_alsamidi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "core/os/midi_driver.h"
3737
#include "core/os/mutex.h"
3838
#include "core/os/thread.h"
39+
#include "core/safe_refcount.h"
3940
#include "core/vector.h"
4041

4142
#include "../alsa/asound-so_wrap.h"
@@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
4748

4849
Vector<snd_rawmidi_t *> connected_inputs;
4950

50-
bool exit_thread;
51+
SafeFlag exit_thread;
5152

5253
static void thread_func(void *p_udata);
5354

drivers/pulseaudio/audio_driver_pulseaudio.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() {
285285
return ERR_CANT_OPEN;
286286
}
287287

288-
active = false;
289-
thread_exited = false;
290-
exit_thread = false;
288+
active.clear();
289+
exit_thread.clear();
291290

292291
mix_rate = GLOBAL_GET("audio/mix_rate");
293292

@@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
384383
size_t avail_bytes = 0;
385384
uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();
386385

387-
while (!ad->exit_thread) {
386+
while (!ad->exit_thread.is_set()) {
388387
size_t read_bytes = 0;
389388
size_t written_bytes = 0;
390389

@@ -394,7 +393,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
394393

395394
int16_t *out_ptr = ad->samples_out.ptrw();
396395

397-
if (!ad->active) {
396+
if (!ad->active.is_set()) {
398397
for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
399398
out_ptr[i] = 0;
400399
}
@@ -464,8 +463,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
464463

465464
err = ad->init_device();
466465
if (err != OK) {
467-
ad->active = false;
468-
ad->exit_thread = true;
466+
ad->active.clear();
467+
ad->exit_thread.set();
469468
break;
470469
}
471470
}
@@ -503,8 +502,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
503502
Error err = ad->init_device();
504503
if (err != OK) {
505504
ERR_PRINT("PulseAudio: init_device error");
506-
ad->active = false;
507-
ad->exit_thread = true;
505+
ad->active.clear();
506+
ad->exit_thread.set();
508507
break;
509508
}
510509

@@ -557,8 +556,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
557556

558557
err = ad->capture_init_device();
559558
if (err != OK) {
560-
ad->active = false;
561-
ad->exit_thread = true;
559+
ad->active.clear();
560+
ad->exit_thread.set();
562561
break;
563562
}
564563
}
@@ -573,12 +572,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
573572
OS::get_singleton()->delay_usec(1000);
574573
}
575574
}
576-
577-
ad->thread_exited = true;
578575
}
579576

580577
void AudioDriverPulseAudio::start() {
581-
active = true;
578+
active.set();
582579
}
583580

584581
int AudioDriverPulseAudio::get_mix_rate() const {
@@ -663,7 +660,7 @@ void AudioDriverPulseAudio::finish() {
663660
return;
664661
}
665662

666-
exit_thread = true;
663+
exit_thread.set();
667664
thread.wait_to_finish();
668665

669666
finish_device();
@@ -840,9 +837,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() :
840837
channels(0),
841838
pa_ready(0),
842839
pa_status(0),
843-
active(false),
844-
thread_exited(false),
845-
exit_thread(false),
846840
latency(0) {
847841
samples_in.clear();
848842
samples_out.clear();

drivers/pulseaudio/audio_driver_pulseaudio.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "core/os/mutex.h"
3737
#include "core/os/thread.h"
38+
#include "core/safe_refcount.h"
3839
#include "servers/audio_server.h"
3940

4041
#include "pulse-so_wrap.h"
@@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver {
7071
Array pa_devices;
7172
Array pa_rec_devices;
7273

73-
bool active;
74-
bool thread_exited;
75-
mutable bool exit_thread;
74+
SafeFlag active;
75+
SafeFlag exit_thread;
7676

7777
float latency;
7878

drivers/wasapi/audio_driver_wasapi.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,12 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
365365
}
366366

367367
Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
368-
if (p_device->active) {
368+
if (p_device->active.is_set()) {
369369
if (p_device->audio_client) {
370370
p_device->audio_client->Stop();
371371
}
372372

373-
p_device->active = false;
373+
p_device->active.clear();
374374
}
375375

376376
SAFE_RELEASE(p_device->audio_client)
@@ -396,8 +396,7 @@ Error AudioDriverWASAPI::init() {
396396
ERR_PRINT("WASAPI: init_render_device error");
397397
}
398398

399-
exit_thread = false;
400-
thread_exited = false;
399+
exit_thread.clear();
401400

402401
thread.start(thread_func, this);
403402

@@ -543,15 +542,15 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
543542
uint32_t avail_frames = 0;
544543
uint32_t write_ofs = 0;
545544

546-
while (!ad->exit_thread) {
545+
while (!ad->exit_thread.is_set()) {
547546
uint32_t read_frames = 0;
548547
uint32_t written_frames = 0;
549548

550549
if (avail_frames == 0) {
551550
ad->lock();
552551
ad->start_counting_ticks();
553552

554-
if (ad->audio_output.active) {
553+
if (ad->audio_output.active.is_set()) {
555554
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
556555
} else {
557556
for (int i = 0; i < ad->samples_in.size(); i++) {
@@ -617,7 +616,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
617616
}
618617
} else {
619618
ERR_PRINT("WASAPI: Get buffer error");
620-
ad->exit_thread = true;
619+
ad->exit_thread.set();
621620
}
622621
}
623622
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
@@ -666,7 +665,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
666665
write_ofs = 0;
667666
}
668667

669-
if (ad->audio_input.active) {
668+
if (ad->audio_input.active.is_set()) {
670669
UINT32 packet_length = 0;
671670
BYTE *data;
672671
UINT32 num_frames_available;
@@ -745,8 +744,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
745744
OS::get_singleton()->delay_usec(1000);
746745
}
747746
}
748-
749-
ad->thread_exited = true;
750747
}
751748

752749
void AudioDriverWASAPI::start() {
@@ -755,7 +752,7 @@ void AudioDriverWASAPI::start() {
755752
if (hr != S_OK) {
756753
ERR_PRINT("WASAPI: Start failed");
757754
} else {
758-
audio_output.active = true;
755+
audio_output.active.set();
759756
}
760757
}
761758
}
@@ -769,7 +766,7 @@ void AudioDriverWASAPI::unlock() {
769766
}
770767

771768
void AudioDriverWASAPI::finish() {
772-
exit_thread = true;
769+
exit_thread.set();
773770
thread.wait_to_finish();
774771

775772
finish_capture_device();
@@ -783,19 +780,19 @@ Error AudioDriverWASAPI::capture_start() {
783780
return err;
784781
}
785782

786-
if (audio_input.active) {
783+
if (audio_input.active.is_set()) {
787784
return FAILED;
788785
}
789786

790787
audio_input.audio_client->Start();
791-
audio_input.active = true;
788+
audio_input.active.set();
792789
return OK;
793790
}
794791

795792
Error AudioDriverWASAPI::capture_stop() {
796-
if (audio_input.active) {
793+
if (audio_input.active.is_set()) {
797794
audio_input.audio_client->Stop();
798-
audio_input.active = false;
795+
audio_input.active.clear();
799796

800797
return OK;
801798
}
@@ -827,9 +824,6 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
827824
channels = 0;
828825
mix_rate = 0;
829826
buffer_frames = 0;
830-
831-
thread_exited = false;
832-
exit_thread = false;
833827
}
834828

835829
#endif

0 commit comments

Comments
 (0)