Bug 1681750 - Fix random GamepadPlatformService::RemoveChannelParent crashes r=haik

The most likely cause for the crashes seems like IPDL intermittently calling GamepadEventChannelParent::ActorDestroy() multiple times on the same object.

This adds a wrapper to stop that behavior (if it's the root cause), and also to fire off release assertions at several other potential causes.

Hopefully we see this crash signature disappear.

Differential Revision: https://phabricator.services.mozilla.com/D99720
This commit is contained in:
Chris Martin 2020-12-15 00:01:19 +00:00
Родитель 42d6c7ccea
Коммит 43bb3444bc
3 изменённых файлов: 19 добавлений и 6 удалений

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

@ -264,7 +264,7 @@ void GamepadPlatformService::AddChannelParentInternal(
const RefPtr<GamepadEventChannelParent>& aParent) {
MutexAutoLock autoLock(mMutex);
MOZ_ASSERT(!mChannelParents.Contains(aParent));
MOZ_RELEASE_ASSERT(!mChannelParents.Contains(aParent));
mChannelParents.AppendElement(aParent);
// Inform the new channel of all the gamepads that have already been added
@ -279,7 +279,7 @@ bool GamepadPlatformService::RemoveChannelParentInternal(
GamepadEventChannelParent* aParent) {
MutexAutoLock autoLock(mMutex);
MOZ_ASSERT(mChannelParents.Contains(aParent));
MOZ_RELEASE_ASSERT(mChannelParents.Contains(aParent));
// If there is only one channel left, we destroy the singleton instead of
// unregistering the channel
@ -318,7 +318,8 @@ void GamepadPlatformService::RemoveChannelParent(
// is created or removed in Background thread
AssertIsOnBackgroundThread();
MOZ_ASSERT(aParent);
MOZ_ASSERT(gGamepadPlatformServiceSingleton);
MOZ_RELEASE_ASSERT(gGamepadPlatformServiceSingleton);
// RemoveChannelParentInternal will refuse to remove the last channel
// In that case, we should destroy the singleton
@ -328,9 +329,14 @@ void GamepadPlatformService::RemoveChannelParent(
GamepadMonitoringState::GetSingleton().Set(false);
StopGamepadMonitoring();
// At this point, any monitor threads should be stopped so we don't need
// synchronization
// At this point, any monitor threads should be stopped and the only
// reference to the singleton should be the global one
// We should never be destroying the singleton with event channels left in it
MOZ_RELEASE_ASSERT(
gGamepadPlatformServiceSingleton->mChannelParents.Length() == 1);
// The only reference to the singleton should be the global one
MOZ_RELEASE_ASSERT(gGamepadPlatformServiceSingleton->mRefCnt.get() == 1);
gGamepadPlatformServiceSingleton = nullptr;

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

@ -56,7 +56,13 @@ GamepadEventChannelParent::GamepadEventChannelParent() {
void GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
AssertIsOnBackgroundThread();
GamepadPlatformService::RemoveChannelParent(this);
// TODO - This is here because I suspect that IPDL is calling ActorDestroy
// multiple times. If this fixes the random crashes in Bug 1681750, it might
// be worth investigating further.
if (!mShutdown) {
GamepadPlatformService::RemoveChannelParent(this);
mShutdown = true;
}
}
mozilla::ipc::IPCResult GamepadEventChannelParent::RecvVibrateHaptic(

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

@ -41,6 +41,7 @@ class GamepadEventChannelParent final : public PGamepadEventChannelParent {
GamepadEventChannelParent();
~GamepadEventChannelParent() = default;
bool mShutdown{false};
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
};