aaudio: fix race when disconnecting
When disconnecting more than one stream,
and the apps reopen the streams,
there was a race condition that resulted
in the first app getting a Legacy stream instead of an
MMAP stream. That is because it was disconnected before the
other streams had stopped.
Now we run the stop loop before the disconnect loop
to prevent the race.
Bug: 158316262
Test: test_steal_exclusive -r0 -d0 -s
Change-Id: Ib8efde9c2f94f6ab1ba3475d88b45d373cc8d3bb
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 15cbd82..ceefe93 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -95,9 +95,16 @@
mRegisteredStreams.swap(streamsDisconnected);
}
mConnected.store(false);
+ // We need to stop all the streams before we disconnect them.
+ // Otherwise there is a race condition where the first disconnected app
+ // tries to reopen a stream as MMAP but is blocked by the second stream,
+ // which hasn't stopped yet. Then the first app ends up with a Legacy stream.
for (const auto &stream : streamsDisconnected) {
- ALOGD("%s() - stop and disconnect port %d", __func__, stream->getPortHandle());
+ ALOGD("%s() - stop(), port = %d", __func__, stream->getPortHandle());
stream->stop();
+ }
+ for (const auto &stream : streamsDisconnected) {
+ ALOGD("%s() - disconnect(), port = %d", __func__, stream->getPortHandle());
stream->disconnect();
}
return streamsDisconnected;