ClientThing.h (3637B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef _mozilla_dom_ClientThing_h 7 #define _mozilla_dom_ClientThing_h 8 9 #include "nsTArray.h" 10 11 namespace mozilla::dom { 12 13 // Base class representing various Client "things" such as ClientHandle, 14 // ClientSource, and ClientManager. Currently it provides a common set 15 // of code for handling activation and shutdown of IPC actors. 16 template <typename ActorType> 17 class ClientThing { 18 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 19 static const uint32_t kMagic1 = 0xC9FE2C9C; 20 static const uint32_t kMagic2 = 0x832072D4; 21 #endif 22 23 ActorType* mActor; 24 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 25 uint32_t mMagic1; 26 uint32_t mMagic2; 27 #endif 28 bool mShutdown; 29 30 protected: 31 ClientThing() 32 : mActor(nullptr) 33 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 34 , 35 mMagic1(kMagic1), 36 mMagic2(kMagic2) 37 #endif 38 , 39 mShutdown(false) { 40 } 41 42 ~ClientThing() { 43 AssertIsValid(); 44 ShutdownThing(); 45 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 46 mMagic1 = 0; 47 mMagic2 = 0; 48 #endif 49 } 50 51 void AssertIsValid() const { 52 MOZ_DIAGNOSTIC_ASSERT(mMagic1 == kMagic1); 53 MOZ_DIAGNOSTIC_ASSERT(mMagic2 == kMagic2); 54 } 55 56 // Return the current actor. 57 ActorType* GetActor() const { 58 AssertIsValid(); 59 return mActor; 60 } 61 62 // Returns true if ShutdownThing() has been called. 63 bool IsShutdown() const { 64 AssertIsValid(); 65 return mShutdown; 66 } 67 68 // Conditionally execute the given callable based on the current state. 69 template <typename Callable> 70 void MaybeExecute( 71 const Callable& aSuccess, const std::function<void()>& aFailure = [] {}) { 72 AssertIsValid(); 73 if (mShutdown) { 74 aFailure(); 75 return; 76 } 77 MOZ_DIAGNOSTIC_ASSERT(mActor); 78 aSuccess(mActor); 79 } 80 81 // Attach activate the thing by attaching its underlying IPC actor. This 82 // will make the thing register as the actor's owner as well. The actor 83 // must call RevokeActor() to clear this weak back reference before its 84 // destroyed. 85 void ActivateThing(ActorType* aActor) { 86 AssertIsValid(); 87 MOZ_DIAGNOSTIC_ASSERT(aActor); 88 MOZ_DIAGNOSTIC_ASSERT(!mActor); 89 MOZ_DIAGNOSTIC_ASSERT(!mShutdown); 90 mActor = aActor; 91 mActor->SetOwner(this); 92 } 93 94 // Start destroying the underlying actor and disconnect the thing. 95 void ShutdownThing() { 96 AssertIsValid(); 97 if (mShutdown) { 98 return; 99 } 100 mShutdown = true; 101 102 // If we are shutdown before the actor, then clear the weak references 103 // between the actor and the thing. 104 if (mActor) { 105 mActor->RevokeOwner(this); 106 mActor->MaybeStartTeardown(); 107 mActor = nullptr; 108 } 109 110 OnShutdownThing(); 111 } 112 113 // Allow extending classes to take action when shutdown. 114 virtual void OnShutdownThing() { 115 // by default do nothing 116 } 117 118 public: 119 // Clear the weak references between the thing and its IPC actor. 120 void RevokeActor(ActorType* aActor) { 121 AssertIsValid(); 122 MOZ_DIAGNOSTIC_ASSERT(mActor); 123 MOZ_DIAGNOSTIC_ASSERT(mActor == aActor); 124 mActor->RevokeOwner(this); 125 mActor = nullptr; 126 127 // Also consider the ClientThing shutdown. We simply set the flag 128 // instead of calling ShutdownThing() to avoid calling MaybeStartTeardown() 129 // on the destroyed actor. 130 mShutdown = true; 131 132 OnShutdownThing(); 133 } 134 }; 135 136 } // namespace mozilla::dom 137 138 #endif // _mozilla_dom_ClientThing_h