Bug 1755700: Use AgileReference for cross-apartment AudioSessionControl use r=Jamie

A deadlock issue with our main thread audio playback handling arises when we try to destroy the AudioSessionControl from the MTA, despite it being an MTA object.  We therefore dispatch its destruction to the main thread (STA) so the deadlock is impossible.  In order to use it from the STA, we should wrap it in an AgileReference.

Differential Revision: https://phabricator.services.mozilla.com/D152301
This commit is contained in:
David Parks 2022-07-29 19:32:14 +00:00
Родитель 38ae048304
Коммит 75d0f3b74f
1 изменённых файлов: 17 добавлений и 2 удалений

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "mozilla/Attributes.h"
#include "mozilla/mscom/AgileReference.h"
#include "mozilla/mscom/Utils.h"
#include "mozilla/Mutex.h"
#include "mozilla/WindowsVersion.h"
@ -249,9 +250,23 @@ void AudioSession::StopInternal(const MutexAutoLock& aProofOfLock) {
// Deleting the IAudioSessionControl COM object requires the STA/main thread.
// Audio code may concurrently be running on the main thread and it may
// block waiting for this to complete, creating deadlock. So we destroy the
// IAudioSessionControl on the main thread instead.
// IAudioSessionControl on the main thread instead. In order to do that, we
// need to marshall the object to the main thread's apartment with an
// AgileReference.
const IID IID_IAudioSessionControl = __uuidof(IAudioSessionControl);
auto agileAsc = MakeUnique<mozilla::mscom::AgileReference>(
IID_IAudioSessionControl, mAudioSessionControl);
mAudioSessionControl = nullptr;
NS_DispatchToMainThread(NS_NewRunnableFunction(
"FreeAudioSession", [asc = std::move(mAudioSessionControl)] { /* */ }));
"FreeAudioSession",
[agileAsc = std::move(agileAsc), IID_IAudioSessionControl] {
RefPtr<IAudioSessionControl> toDelete;
[[maybe_unused]] HRESULT hr = agileAsc->Resolve(
IID_IAudioSessionControl, getter_AddRefs(toDelete));
MOZ_ASSERT(SUCCEEDED(hr));
// Now release the AgileReference which holds our only reference to the
// IAudioSessionControl.
}));
}
void CopynsID(nsID& lhs, const nsID& rhs) {