-another approach to solving the deadlock problem :|

This commit is contained in:
Juan Linietsky 2015-12-21 10:51:27 -03:00
parent 46dee92c8e
commit 9bf7adfc1f
3 changed files with 20 additions and 27 deletions

View file

@ -75,7 +75,10 @@ void StreamPlayer::sp_update() {
//check that all this audio has been flushed before stopping the stream //check that all this audio has been flushed before stopping the stream
int to_mix = resampler.get_total() - resampler.get_todo(); int to_mix = resampler.get_total() - resampler.get_todo();
if (to_mix==0) { if (to_mix==0) {
stop(); if (!stop_request) {
stop_request=true;
call_deferred("stop");
}
return; return;
} }
@ -164,6 +167,7 @@ void StreamPlayer::stop() {
//_THREAD_SAFE_METHOD_ //_THREAD_SAFE_METHOD_
AudioServer::get_singleton()->stream_set_active(stream_rid,false); AudioServer::get_singleton()->stream_set_active(stream_rid,false);
stop_request=false;
playback->stop(); playback->stop();
resampler.flush(); resampler.flush();
@ -389,6 +393,7 @@ StreamPlayer::StreamPlayer() {
stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream); stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream);
buffering_ms=500; buffering_ms=500;
loop_point=0; loop_point=0;
stop_request=false;
} }

View file

@ -66,6 +66,7 @@ class StreamPlayer : public Node {
float volume; float volume;
float loop_point; float loop_point;
int buffering_ms; int buffering_ms;
volatile bool stop_request;
AudioRBResampler resampler; AudioRBResampler resampler;

View file

@ -30,10 +30,6 @@
#include "globals.h" #include "globals.h"
#include "os/os.h" #include "os/os.h"
#ifdef NO_THREADS
#define NO_AUDIO_THREADS
#endif
struct _AudioDriverLock { struct _AudioDriverLock {
_AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->lock(); } _AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->lock(); }
@ -663,7 +659,7 @@ bool AudioServerSW::voice_is_active(RID p_voice) const {
RID AudioServerSW::audio_stream_create(AudioStream *p_stream) { RID AudioServerSW::audio_stream_create(AudioStream *p_stream) {
AUDIO_LOCK AUDIO_LOCK
Stream *s = memnew(Stream); Stream *s = memnew(Stream);
s->audio_stream=p_stream; s->audio_stream=p_stream;
s->event_stream=NULL; s->event_stream=NULL;
@ -701,24 +697,16 @@ void AudioServerSW::stream_set_active(RID p_stream, bool p_active) {
if (s->active==p_active) if (s->active==p_active)
return; return;
if (!thread || thread->get_ID()!=Thread::get_caller_ID()) { AUDIO_LOCK;
//do not lock in mix thread s->active=p_active;
lock(); if (p_active)
} s->E=active_audio_streams.push_back(s);
{ else {
s->active=p_active; active_audio_streams.erase(s->E);
if (p_active) s->E=NULL;
s->E=active_audio_streams.push_back(s);
else {
active_audio_streams.erase(s->E);
s->E=NULL;
}
}
if (!thread || thread->get_ID()!=Thread::get_caller_ID()) {
//do not lock in mix thread
unlock();
} }
} }
bool AudioServerSW::stream_is_active(RID p_stream) const { bool AudioServerSW::stream_is_active(RID p_stream) const {
@ -779,7 +767,7 @@ void AudioServerSW::_thread_func(void *self) {
AudioServerSW *as=(AudioServerSW *)self; AudioServerSW *as=(AudioServerSW *)self;
//as->thread->set_name("AudioServerSW"); as->thread->set_name("AudioServerSW");
while (!as->exit_update_thread) { while (!as->exit_update_thread) {
as->_update_streams(true); as->_update_streams(true);
@ -818,17 +806,16 @@ void AudioServerSW::init() {
if (AudioDriverSW::get_singleton()) if (AudioDriverSW::get_singleton())
AudioDriverSW::get_singleton()->start(); AudioDriverSW::get_singleton()->start();
#ifndef NO_AUDIO_THREADS #ifndef NO_THREADS
exit_update_thread=false; exit_update_thread=false;
thread = Thread::create(_thread_func,this); thread = Thread::create(_thread_func,this);
thread->set_name("AudioServerSW");
#endif #endif
} }
void AudioServerSW::finish() { void AudioServerSW::finish() {
#ifndef NO_AUDIO_THREADS #ifndef NO_THREADS
exit_update_thread=true; exit_update_thread=true;
Thread::wait_to_finish(thread); Thread::wait_to_finish(thread);
memdelete(thread); memdelete(thread);
@ -861,7 +848,7 @@ void AudioServerSW::_update_streams(bool p_thread) {
void AudioServerSW::update() { void AudioServerSW::update() {
_update_streams(false); _update_streams(false);
#ifdef NO_AUDIO_THREADS #ifdef NO_THREADS
_update_streams(true); _update_streams(true);
#endif #endif