From b99e64a0e3759d326b53578516a4ca5084046e7c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 3 Feb 2018 13:54:42 -0800 Subject: [PATCH] Provide more descriptive messages to disconnection events --- Alc/ALc.c | 10 +++++----- Alc/ALu.c | 43 ++++++++++++++++++++++++++++++------------- Alc/backends/alsa.c | 13 +++++++------ Alc/backends/dsound.c | 14 ++++++++------ Alc/backends/jack.c | 2 +- Alc/backends/mmdevapi.c | 10 +++++----- Alc/backends/opensl.c | 9 +++++---- Alc/backends/oss.c | 9 +++++---- Alc/backends/pulseaudio.c | 17 +++++++++-------- Alc/backends/qsa.c | 11 ++++++----- Alc/backends/sndio.c | 2 +- Alc/backends/solaris.c | 5 +++-- Alc/backends/wave.c | 2 +- OpenAL32/Include/alu.h | 2 +- 14 files changed, 87 insertions(+), 62 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index dfda8381..3c9598ca 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -3810,7 +3810,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin if(err == ALC_INVALID_DEVICE) { V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Device update failure"); V0(device->Backend,unlock)(); } ALCdevice_DecRef(device); @@ -4397,7 +4397,7 @@ ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) device->Flags |= DEVICE_RUNNING; else { - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Device start failure"); alcSetError(device, ALC_INVALID_DEVICE); } } @@ -4621,10 +4621,10 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) device->Flags |= DEVICE_RUNNING; else { - alcSetError(device, ALC_INVALID_DEVICE); V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Device start failure"); V0(device->Backend,unlock)(); + alcSetError(device, ALC_INVALID_DEVICE); } } } @@ -4694,7 +4694,7 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi if(err == ALC_INVALID_DEVICE) { V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Device start failure"); V0(device->Backend,unlock)(); } ALCdevice_DecRef(device); diff --git a/Alc/ALu.c b/Alc/ALu.c index 2a89f455..9f4f7a30 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1850,30 +1850,47 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples) } -void aluHandleDisconnect(ALCdevice *device) +void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) { ALCcontext *ctx; + AsyncEvent evt; + va_list args; + int msglen; device->Connected = ALC_FALSE; + evt.EnumType = EventType_Disconnected; + evt.Type = AL_EVENT_TYPE_DISCONNECTED_SOFT; + evt.ObjectId = 0; + evt.Param = 0; + + va_start(args, msg); + msglen = vsnprintf(evt.Message, sizeof(evt.Message), msg, args); + va_end(args); + + if(msglen < 0 || (size_t)msglen >= sizeof(evt.Message)) + { + evt.Message[sizeof(evt.Message)-1] = 0; + msglen = (int)strlen(evt.Message); + } + if(msglen > 0) + msg = evt.Message; + else + { + msg = ""; + msglen = (int)strlen(msg); + } + ctx = ATOMIC_LOAD_SEQ(&device->ContextList); while(ctx) { ALsizei i; - if((ATOMIC_LOAD(&ctx->EnabledEvts, almemory_order_acquire)&EventType_Disconnected)) + if((ATOMIC_LOAD(&ctx->EnabledEvts, almemory_order_acquire)&EventType_Disconnected) && + ll_ringbuffer_write_space(ctx->AsyncEvents) > 0) { - AsyncEvent evt; - evt.EnumType = EventType_Disconnected; - evt.Type = AL_EVENT_TYPE_DISCONNECTED_SOFT; - evt.ObjectId = 0; - evt.Param = 0; - strcpy(evt.Message, "Device disconnected"); - if(ll_ringbuffer_write_space(ctx->AsyncEvents) > 0) - { - ll_ringbuffer_write(ctx->AsyncEvents, (const char*)&evt, 1); - alsem_post(&ctx->EventSem); - } + ll_ringbuffer_write(ctx->AsyncEvents, (const char*)&evt, 1); + alsem_post(&ctx->EventSem); } for(i = 0;i < ctx->VoiceCount;i++) diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index 915d31d3..72e2936f 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -502,7 +502,7 @@ static int ALCplaybackAlsa_mixerProc(void *ptr) { ERR("Invalid state detected: %s\n", snd_strerror(state)); ALCplaybackAlsa_lock(self); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Bad state: %s", snd_strerror(state)); ALCplaybackAlsa_unlock(self); break; } @@ -592,7 +592,7 @@ static int ALCplaybackAlsa_mixerNoMMapProc(void *ptr) { ERR("Invalid state detected: %s\n", snd_strerror(state)); ALCplaybackAlsa_lock(self); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Bad state: %s", snd_strerror(state)); ALCplaybackAlsa_unlock(self); break; } @@ -1155,7 +1155,8 @@ static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self) if(err < 0) { ERR("start failed: %s\n", snd_strerror(err)); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, "Capture state failure: %s", + snd_strerror(err)); return ALC_FALSE; } @@ -1249,7 +1250,7 @@ static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buff if(amt < 0) { ERR("restore error: %s\n", snd_strerror(amt)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt)); break; } /* If the amount available is less than what's asked, we lost it @@ -1290,7 +1291,7 @@ static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self) if(avail < 0) { ERR("restore error: %s\n", snd_strerror(avail)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(avail)); } } @@ -1329,7 +1330,7 @@ static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self) if(amt < 0) { ERR("restore error: %s\n", snd_strerror(amt)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Capture recovery failure: %s", snd_strerror(amt)); break; } avail = amt; diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index 3d130615..bca8b7f0 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -267,7 +267,7 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Failed to get buffer caps: 0x%lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure retrieving playback buffer info: 0x%lx", err); ALCdevice_Unlock(device); return 1; } @@ -291,7 +291,7 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Failed to play buffer: 0x%lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure starting playback: 0x%lx", err); ALCdevice_Unlock(device); return 1; } @@ -339,7 +339,7 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Buffer lock error: %#lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to lock output buffer: 0x%lx", err); ALCdevice_Unlock(device); return 1; } @@ -894,7 +894,8 @@ static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("start failed: 0x%08lx\n", hr); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, + "Failure starting capture: 0x%lx", hr); return ALC_FALSE; } @@ -909,7 +910,8 @@ static void ALCdsoundCapture_stop(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("stop failed: 0x%08lx\n", hr); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, + "Failure stopping capture: 0x%lx", hr); } } @@ -959,7 +961,7 @@ static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("update failed: 0x%08lx\n", hr); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure retrieving capture data: 0x%lx", hr); } done: diff --git a/Alc/backends/jack.c b/Alc/backends/jack.c index 14032d45..2f17bbf6 100644 --- a/Alc/backends/jack.c +++ b/Alc/backends/jack.c @@ -241,7 +241,7 @@ static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg) if(!self->Ring) { ERR("Failed to reallocate ringbuffer\n"); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to reallocate %u-sample buffer", bufsize); } ALCjackPlayback_unlock(self); return 0; diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c index d63d22df..5f1dbba8 100644 --- a/Alc/backends/mmdevapi.c +++ b/Alc/backends/mmdevapi.c @@ -632,7 +632,7 @@ FORCE_ALIGN static int ALCmmdevPlayback_mixerProc(void *arg) { ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr); V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "COM init failed: 0x%08lx", hr); V0(device->Backend,unlock)(); return 1; } @@ -649,7 +649,7 @@ FORCE_ALIGN static int ALCmmdevPlayback_mixerProc(void *arg) { ERR("Failed to get padding: 0x%08lx\n", hr); V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to retrieve buffer padding: 0x%08lx", hr); V0(device->Backend,unlock)(); break; } @@ -679,7 +679,7 @@ FORCE_ALIGN static int ALCmmdevPlayback_mixerProc(void *arg) { ERR("Failed to buffer data: 0x%08lx\n", hr); V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to send playback samples: 0x%08lx", hr); V0(device->Backend,unlock)(); break; } @@ -1326,7 +1326,7 @@ FORCE_ALIGN int ALCmmdevCapture_recordProc(void *arg) { ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr); V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "COM init failed: 0x%08lx", hr); V0(device->Backend,unlock)(); return 1; } @@ -1415,7 +1415,7 @@ FORCE_ALIGN int ALCmmdevCapture_recordProc(void *arg) if(FAILED(hr)) { V0(device->Backend,lock)(); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to capture samples: 0x%08lx", hr); V0(device->Backend,unlock)(); break; } diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c index fb56b67c..93d2e521 100644 --- a/Alc/backends/opensl.c +++ b/Alc/backends/opensl.c @@ -255,7 +255,7 @@ static int ALCopenslPlayback_mixerProc(void *arg) if(SL_RESULT_SUCCESS != result) { ALCopenslPlayback_lock(self); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to get playback buffer: 0x%08x", result); ALCopenslPlayback_unlock(self); return 1; } @@ -283,7 +283,7 @@ static int ALCopenslPlayback_mixerProc(void *arg) } if(SL_RESULT_SUCCESS != result) { - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to start platback: 0x%08x", result); break; } @@ -919,7 +919,8 @@ static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self) if(SL_RESULT_SUCCESS != result) { ALCopenslCapture_lock(self); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, + "Failed to start capture: 0x%08x", result); ALCopenslCapture_unlock(self); return ALC_FALSE; } @@ -1002,7 +1003,7 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid * if(SL_RESULT_SUCCESS != result) { ALCopenslCapture_lock(self); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to update capture buffer: 0x%08x", result); ALCopenslCapture_unlock(self); return ALC_INVALID_DEVICE; } diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c index b2d9c555..9b0c2d42 100644 --- a/Alc/backends/oss.c +++ b/Alc/backends/oss.c @@ -299,7 +299,7 @@ static int ALCplaybackOSS_mixerProc(void *ptr) if(errno == EINTR) continue; ERR("select failed: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed waiting for playback buffer: %s", strerror(errno)); break; } else if(sret == 0) @@ -319,7 +319,8 @@ static int ALCplaybackOSS_mixerProc(void *ptr) if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) continue; ERR("write failed: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed writing playback samples: %s", + strerror(errno)); break; } @@ -566,7 +567,7 @@ static int ALCcaptureOSS_recordProc(void *ptr) if(errno == EINTR) continue; ERR("select failed: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to check capture samples: %s", strerror(errno)); break; } else if(sret == 0) @@ -583,7 +584,7 @@ static int ALCcaptureOSS_recordProc(void *ptr) { ERR("read failed: %s\n", strerror(errno)); ALCcaptureOSS_lock(self); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed reading capture samples: %s", strerror(errno)); ALCcaptureOSS_unlock(self); break; } diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index bcfbb6c2..28858a72 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -650,7 +650,7 @@ static void ALCpulsePlayback_contextStateCallback(pa_context *context, void *pda if(pa_context_get_state(context) == PA_CONTEXT_FAILED) { ERR("Received context failure!\n"); - aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice, "Playback state failure"); } pa_threaded_mainloop_signal(self->loop, 0); } @@ -661,7 +661,7 @@ static void ALCpulsePlayback_streamStateCallback(pa_stream *stream, void *pdata) if(pa_stream_get_state(stream) == PA_STREAM_FAILED) { ERR("Received stream failure!\n"); - aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice, "Playback stream failure"); } pa_threaded_mainloop_signal(self->loop, 0); } @@ -835,7 +835,7 @@ static int ALCpulsePlayback_mixerProc(void *ptr) if(len < 0) { ERR("Failed to get writable size: %ld", (long)len); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to get writable size: %ld", (long)len); break; } @@ -1388,7 +1388,7 @@ static void ALCpulseCapture_contextStateCallback(pa_context *context, void *pdat if(pa_context_get_state(context) == PA_CONTEXT_FAILED) { ERR("Received context failure!\n"); - aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice, "Capture state failure"); } pa_threaded_mainloop_signal(self->loop, 0); } @@ -1399,7 +1399,7 @@ static void ALCpulseCapture_streamStateCallback(pa_stream *stream, void *pdata) if(pa_stream_get_state(stream) == PA_STREAM_FAILED) { ERR("Received stream failure!\n"); - aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice, "Capture stream failure"); } pa_threaded_mainloop_signal(self->loop, 0); } @@ -1662,14 +1662,15 @@ static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *bu state = pa_stream_get_state(self->stream); if(!PA_STREAM_IS_GOOD(state)) { - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Bad capture state: %u", state); break; } if(pa_stream_peek(self->stream, &self->cap_store, &self->cap_len) < 0) { ERR("pa_stream_peek() failed: %s\n", pa_strerror(pa_context_errno(self->context))); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed retrieving capture samples: %s", + pa_strerror(pa_context_errno(self->context))); break; } self->cap_remain = self->cap_len; @@ -1710,7 +1711,7 @@ static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self) if(got < 0) { ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed getting readable size: %s", pa_strerror(got)); } else if((size_t)got > self->cap_len) readable += got - self->cap_len; diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c index 614d738c..484cadaa 100644 --- a/Alc/backends/qsa.c +++ b/Alc/backends/qsa.c @@ -220,7 +220,7 @@ FORCE_ALIGN static int qsa_proc_playback(void *ptr) if(sret == -1) { ERR("select error: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed waiting for playback buffer: %s", strerror(errno)); break; } if(sret == 0) @@ -251,7 +251,7 @@ FORCE_ALIGN static int qsa_proc_playback(void *ptr) { if(snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK) < 0) { - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Playback recovery failed"); break; } } @@ -847,7 +847,7 @@ static ALCuint qsa_available_samples(CaptureWrapper *self) if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0) { ERR("capture prepare failed: %s\n", snd_strerror(rstatus)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed capture recovery: %s", snd_strerror(rstatus)); return 0; } @@ -890,7 +890,7 @@ static ALCenum qsa_capture_samples(CaptureWrapper *self, ALCvoid *buffer, ALCuin switch (selectret) { case -1: - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to check capture samples"); return ALC_INVALID_DEVICE; case 0: break; @@ -921,7 +921,8 @@ static ALCenum qsa_capture_samples(CaptureWrapper *self, ALCvoid *buffer, ALCuin if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0) { ERR("capture prepare failed: %s\n", snd_strerror(rstatus)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed capture recovery: %s", + snd_strerror(rstatus)); return ALC_INVALID_DEVICE; } snd_pcm_capture_go(data->pcmHandle); diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c index f7b9af69..06a434d9 100644 --- a/Alc/backends/sndio.c +++ b/Alc/backends/sndio.c @@ -117,7 +117,7 @@ static int ALCsndioBackend_mixerProc(void *ptr) { ERR("sio_write failed\n"); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to write playback samples"); ALCdevice_Unlock(device); break; } diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index 49bfad3c..fdc62562 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -135,7 +135,7 @@ static int ALCsolarisBackend_mixerProc(void *ptr) if(errno == EINTR) continue; ERR("select failed: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to wait for playback buffer: %s", strerror(errno)); break; } else if(sret == 0) @@ -155,7 +155,8 @@ static int ALCsolarisBackend_mixerProc(void *ptr) if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) continue; ERR("write failed: %s\n", strerror(errno)); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to write playback samples: %s", + strerror(errno)); break; } diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c index ecb066f8..13ffaeec 100644 --- a/Alc/backends/wave.c +++ b/Alc/backends/wave.c @@ -204,7 +204,7 @@ static int ALCwaveBackend_mixerProc(void *ptr) { ERR("Error writing to file\n"); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to write playback samples"); ALCdevice_Unlock(device); break; } diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 0d39729d..920b7b44 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -520,7 +520,7 @@ ALboolean MixSource(struct ALvoice *voice, ALuint SourceID, ALCcontext *Context, void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples); /* Caller must lock the device, and the mixer must not be running. */ -void aluHandleDisconnect(ALCdevice *device); +void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3); void UpdateContextProps(ALCcontext *context); -- 2.11.4.GIT