aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Gregan <[email protected]>2023-03-21 12:44:27 +1300
committerMatthew Gregan <[email protected]>2023-03-22 09:02:06 +1300
commit2071354a69aca7ed6df3b4222e305746c2113f60 (patch)
tree8c52b2c28984fad00e5319b30ebe3712db9cfe2f
parent63c148f602884e001b32905f96fcdb618a6c0a76 (diff)
downloadcubeb-2071354a69aca7ed6df3b4222e305746c2113f60.tar.gz
cubeb-2071354a69aca7ed6df3b4222e305746c2113f60.zip
opensl: Attempt to avoid a race with active callbacks during shutdown.
Based on examining crash dumps and investigating OpenSL workarounds in liboboe, there is a potential race between active buffer callbacks and stream shutdown, resulting in a buffer callback attempting to use a new buffer after stream destroy has freed the backing allocation. Ideally there would be a concrete event to watch for to ensure the last callbacks have completed before destroying the stream, but I'm not aware of one and the existing workaround in liboboe relies on an arbitrary ("long enough") sleep between stopping and destroying streams.
-rw-r--r--src/cubeb_opensl.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/cubeb_opensl.c b/src/cubeb_opensl.c
index efac34d..ba9f208 100644
--- a/src/cubeb_opensl.c
+++ b/src/cubeb_opensl.c
@@ -1655,6 +1655,16 @@ opensl_stream_destroy(cubeb_stream * stm)
{
assert(stm->draining || stm->shutdown);
+ // If we're still draining at stream destroy time, pause the streams now so we
+ // can destroy them safely.
+ if (stm->draining) {
+ opensl_stream_stop(stm);
+ }
+ // Sleep for 10ms to give active streams time to pause so that no further
+ // buffer callbacks occur. Inspired by the same workaround (sleepBeforeClose)
+ // in liboboe.
+ usleep(10 * 1000);
+
if (stm->playerObj) {
(*stm->playerObj)->Destroy(stm->playerObj);
stm->playerObj = NULL;