1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/* -*- 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
|