diff options
author | Phil Burk <philburk@google.com> | 2020-06-05 09:58:26 -0700 |
---|---|---|
committer | Phil Burk <philburk@google.com> | 2021-03-09 01:17:09 +0000 |
commit | 50fd22f3d7eaf0b8dba49e88e1feb6aa99005cff (patch) | |
tree | b5a5e6be9e3031d3e6d11ca0bda870b675b5b302 | |
parent | 10710e468788f7f8e4f51cde751e4df904c6d538 (diff) |
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: 153358911
Bug: 158316262
Test: test_steal_exclusive -r0 -d0 -s
Change-Id: Ib8efde9c2f94f6ab1ba3475d88b45d373cc8d3bb
Merged-In: Ib8efde9c2f94f6ab1ba3475d88b45d373cc8d3bb
(cherry picked from commit 8e2255ad97be8c5665b6bc8973d37c241fb5814b)
-rw-r--r-- | services/oboeservice/AAudioServiceEndpoint.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp index d9e9db1368..1cffe015fb 100644 --- a/services/oboeservice/AAudioServiceEndpoint.cpp +++ b/services/oboeservice/AAudioServiceEndpoint.cpp @@ -95,10 +95,16 @@ void AAudioServiceEndpoint::disconnectRegisteredStreams() { // Stop and disconnect outside mLockStreams to avoid reverse // ordering of AAudioServiceStreamBase::mLock and mLockStreams mConnected.store(false); - for (const auto& stream : streamsToDisconnect) { - ALOGD("disconnectRegisteredStreams() stop and disconnect port %d", - stream->getPortHandle()); + // 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 : streamsToDisconnect) { + ALOGD("%s() - stop(), port = %d", __func__, stream->getPortHandle()); stream->stop(); + } + for (const auto &stream : streamsToDisconnect) { + ALOGD("%s() - disconnect(), port = %d", __func__, stream->getPortHandle()); stream->disconnect(); } } |