Commit ee57a1a4 authored by Andrew Osmond's avatar Andrew Osmond
Browse files

Bug 1374278 - Fix a race condition between GPUChild and CompositorManagerChild...

Bug 1374278 - Fix a race condition between GPUChild and CompositorManagerChild when the GPU process crashes. r=dvander
parent a1222374
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -203,7 +203,11 @@ GPUProcessManager::EnsureGPUReady()
void
GPUProcessManager::EnsureCompositorManagerChild()
{
  if (CompositorManagerChild::IsInitialized()) {
  base::ProcessId gpuPid = EnsureGPUReady()
                           ? mGPUChild->OtherPid()
                           : base::GetCurrentProcId();

  if (CompositorManagerChild::IsInitialized(gpuPid)) {
    return;
  }

+12 −6
Original line number Diff line number Diff line
@@ -19,19 +19,21 @@ namespace layers {
StaticRefPtr<CompositorManagerChild> CompositorManagerChild::sInstance;

/* static */ bool
CompositorManagerChild::IsInitialized()
CompositorManagerChild::IsInitialized(base::ProcessId aGPUPid)
{
  MOZ_ASSERT(NS_IsMainThread());
  return sInstance && sInstance->CanSend();
  // Since GPUChild and CompositorManagerChild will race on ActorDestroy, we
  // cannot know if the CompositorManagerChild is about to be released but has
  // yet to be. As such, we need to verify the GPU PID matches as well.
  return sInstance && sInstance->CanSend() && sInstance->OtherPid() == aGPUPid;
}

/* static */ bool
CompositorManagerChild::InitSameProcess(uint32_t aNamespace)
{
  MOZ_ASSERT(NS_IsMainThread());
  if (NS_WARN_IF(sInstance &&
                 sInstance->OtherPid() == base::GetCurrentProcId())) {
    MOZ_ASSERT_UNREACHABLE("Already initialized");
  if (NS_WARN_IF(IsInitialized(base::GetCurrentProcId()))) {
    MOZ_ASSERT_UNREACHABLE("Already initialized same process");
    return false;
  }

@@ -47,8 +49,12 @@ CompositorManagerChild::Init(Endpoint<PCompositorManagerChild>&& aEndpoint,
{
  MOZ_ASSERT(NS_IsMainThread());
  if (sInstance) {
    // Since GPUChild and CompositorManagerChild will race on ActorDestroy, we
    // cannot know if the CompositorManagerChild has yet to be released or not.
    // To avoid an unnecessary reinitialization, we verify the GPU PID actually
    // changed.
    MOZ_ASSERT(sInstance->mNamespace != aNamespace);
    MOZ_RELEASE_ASSERT(!sInstance->CanSend());
    MOZ_RELEASE_ASSERT(sInstance->OtherPid() != aEndpoint.OtherPid());
  }

  sInstance = new CompositorManagerChild(Move(aEndpoint), aNamespace);
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ class CompositorManagerChild : public PCompositorManagerChild
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorManagerChild)

public:
  static bool IsInitialized();
  static bool IsInitialized(base::ProcessId aPid);
  static bool InitSameProcess(uint32_t aNamespace);
  static bool Init(Endpoint<PCompositorManagerChild>&& aEndpoint,
                   uint32_t aNamespace);