mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	Depends on D145741 Differential Revision: https://phabricator.services.mozilla.com/D145742
		
			
				
	
	
		
			138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
#ifndef _mozilla_dom_ClientThing_h
 | 
						|
#define _mozilla_dom_ClientThing_h
 | 
						|
 | 
						|
#include "nsTArray.h"
 | 
						|
 | 
						|
namespace mozilla::dom {
 | 
						|
 | 
						|
// Base class representing various Client "things" such as ClientHandle,
 | 
						|
// ClientSource, and ClientManager.  Currently it provides a common set
 | 
						|
// of code for handling activation and shutdown of IPC actors.
 | 
						|
template <typename ActorType>
 | 
						|
class ClientThing {
 | 
						|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 | 
						|
  static const uint32_t kMagic1 = 0xC9FE2C9C;
 | 
						|
  static const uint32_t kMagic2 = 0x832072D4;
 | 
						|
#endif
 | 
						|
 | 
						|
  ActorType* mActor;
 | 
						|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 | 
						|
  uint32_t mMagic1;
 | 
						|
  uint32_t mMagic2;
 | 
						|
#endif
 | 
						|
  bool mShutdown;
 | 
						|
 | 
						|
 protected:
 | 
						|
  ClientThing()
 | 
						|
      : mActor(nullptr)
 | 
						|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 | 
						|
        ,
 | 
						|
        mMagic1(kMagic1),
 | 
						|
        mMagic2(kMagic2)
 | 
						|
#endif
 | 
						|
        ,
 | 
						|
        mShutdown(false) {
 | 
						|
  }
 | 
						|
 | 
						|
  ~ClientThing() {
 | 
						|
    AssertIsValid();
 | 
						|
    ShutdownThing();
 | 
						|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 | 
						|
    mMagic1 = 0;
 | 
						|
    mMagic2 = 0;
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  void AssertIsValid() const {
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(mMagic1 == kMagic1);
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(mMagic2 == kMagic2);
 | 
						|
  }
 | 
						|
 | 
						|
  // Return the current actor.
 | 
						|
  ActorType* GetActor() const {
 | 
						|
    AssertIsValid();
 | 
						|
    return mActor;
 | 
						|
  }
 | 
						|
 | 
						|
  // Returns true if ShutdownThing() has been called.
 | 
						|
  bool IsShutdown() const {
 | 
						|
    AssertIsValid();
 | 
						|
    return mShutdown;
 | 
						|
  }
 | 
						|
 | 
						|
  // Conditionally execute the given callable based on the current state.
 | 
						|
  template <typename Callable>
 | 
						|
  void MaybeExecute(
 | 
						|
      const Callable& aSuccess, const std::function<void()>& aFailure = [] {}) {
 | 
						|
    AssertIsValid();
 | 
						|
    if (mShutdown) {
 | 
						|
      aFailure();
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(mActor);
 | 
						|
    aSuccess(mActor);
 | 
						|
  }
 | 
						|
 | 
						|
  // Attach activate the thing by attaching its underlying IPC actor.  This
 | 
						|
  // will make the thing register as the actor's owner as well.  The actor
 | 
						|
  // must call RevokeActor() to clear this weak back reference before its
 | 
						|
  // destroyed.
 | 
						|
  void ActivateThing(ActorType* aActor) {
 | 
						|
    AssertIsValid();
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(aActor);
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(!mActor);
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(!mShutdown);
 | 
						|
    mActor = aActor;
 | 
						|
    mActor->SetOwner(this);
 | 
						|
  }
 | 
						|
 | 
						|
  // Start destroying the underlying actor and disconnect the thing.
 | 
						|
  void ShutdownThing() {
 | 
						|
    AssertIsValid();
 | 
						|
    if (mShutdown) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    mShutdown = true;
 | 
						|
 | 
						|
    // If we are shutdown before the actor, then clear the weak references
 | 
						|
    // between the actor and the thing.
 | 
						|
    if (mActor) {
 | 
						|
      mActor->RevokeOwner(this);
 | 
						|
      mActor->MaybeStartTeardown();
 | 
						|
      mActor = nullptr;
 | 
						|
    }
 | 
						|
 | 
						|
    OnShutdownThing();
 | 
						|
  }
 | 
						|
 | 
						|
  // Allow extending classes to take action when shutdown.
 | 
						|
  virtual void OnShutdownThing() {
 | 
						|
    // by default do nothing
 | 
						|
  }
 | 
						|
 | 
						|
 public:
 | 
						|
  // Clear the weak references between the thing and its IPC actor.
 | 
						|
  void RevokeActor(ActorType* aActor) {
 | 
						|
    AssertIsValid();
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(mActor);
 | 
						|
    MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
 | 
						|
    mActor->RevokeOwner(this);
 | 
						|
    mActor = nullptr;
 | 
						|
 | 
						|
    // Also consider the ClientThing shutdown.  We simply set the flag
 | 
						|
    // instead of calling ShutdownThing() to avoid calling MaybeStartTeardown()
 | 
						|
    // on the destroyed actor.
 | 
						|
    mShutdown = true;
 | 
						|
 | 
						|
    OnShutdownThing();
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace mozilla::dom
 | 
						|
 | 
						|
#endif  // _mozilla_dom_ClientThing_h
 |