Bug 1867190 - Initialise the PHC allocate delay later r=glandium
[gecko.git] / xpcom / threads / EventTargetCapability.h
blob0cd85a75235b5eb99a399d01647f57cea3777ad1
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/. */
7 #ifndef XPCOM_THREADS_EVENTTARGETCAPABILITY_H_
8 #define XPCOM_THREADS_EVENTTARGETCAPABILITY_H_
10 #include "mozilla/ThreadSafety.h"
11 #include "nsIEventTarget.h"
13 namespace mozilla {
15 // A helper to ensure that data access and function usage only take place on a
16 // specific nsIEventTarget.
18 // This class works with Clang's thread safety analysis so that static analysis
19 // can ensure AssertOnCurrentThread is called before using guarded data and
20 // functions.
22 // This means using the class is similar to calling
23 // `MOZ_ASSERT(mTarget->IsOnCurrentThread())`
24 // prior to accessing things we expect to be on `mTarget`. However, using this
25 // helper has the added benefit that static analysis will warn you if you
26 // fail to assert prior to usage.
28 // The following is a basic example of a class using this to ensure
29 // a data member is only accessed on a specific target.
31 // class SomeMediaHandlerThing {
32 // public:
33 // SomeMediaHandlerThing(nsIEventTarget* aTarget) : mTargetCapability(aTarget)
34 // {}
36 // void UpdateMediaState() {
37 // mTargetCapability.Dispatch(
38 // NS_NewRunnableFunction("UpdateMediaState", [this] {
39 // mTargetCapability.AssertOnCurrentThread();
40 // IncreaseMediaCount();
41 // }));
42 // }
44 // private:
45 // void IncreaseMediaCount() MOZ_REQUIRES(mTargetCapability) { mMediaCount +=
46 // 1; }
48 // uint32_t mMediaCount MOZ_GUARDED_BY(mTargetCapability) = 0;
49 // EventTargetCapability<nsIEventTarget> mTargetCapability;
50 // };
52 // NOTE: If you need a thread-safety capability for specifically the main
53 // thread, the static `mozilla::sMainThreadCapability` capability exists, and
54 // can be asserted using `AssertIsOnMainThread()`.
56 template <typename T>
57 class MOZ_CAPABILITY("event target") EventTargetCapability final {
58 static_assert(std::is_base_of_v<nsIEventTarget, T>,
59 "T must derive from nsIEventTarget");
61 public:
62 explicit EventTargetCapability(T* aTarget) : mTarget(aTarget) {
63 MOZ_ASSERT(mTarget, "mTarget should be non-null");
65 ~EventTargetCapability() = default;
67 EventTargetCapability(const EventTargetCapability&) = default;
68 EventTargetCapability(EventTargetCapability&&) = default;
69 EventTargetCapability& operator=(const EventTargetCapability&) = default;
70 EventTargetCapability& operator=(EventTargetCapability&&) = default;
72 void AssertOnCurrentThread() const MOZ_ASSERT_CAPABILITY(this) {
73 MOZ_ASSERT(IsOnCurrentThread());
76 // Allow users to check if we're on the same thread as the event target.
77 bool IsOnCurrentThread() const { return mTarget->IsOnCurrentThread(); }
79 // Allow users to get the event target, so classes don't have to store the
80 // target as a separate member to use it.
81 T* GetEventTarget() const { return mTarget; }
83 // Helper to simplify dispatching to mTarget.
84 nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable,
85 uint32_t aFlags = NS_DISPATCH_NORMAL) const {
86 return mTarget->Dispatch(std::move(aRunnable), aFlags);
89 private:
90 RefPtr<T> mTarget;
93 } // namespace mozilla
95 #endif // XPCOM_THREADS_EVENTTARGETCAPABILITY_H_