Bug 1839170 - Refactor Snap pulling, Add Firefox Snap Core22 and GNOME 42 SDK symbols...
[gecko.git] / ipc / glue / AsyncBlockers.h
blob16e7aa752879563271c6ee6967d25fd265ac2ed1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et ft=cpp : */
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_ipc_AsyncBlockers_h
8 #define mozilla_ipc_AsyncBlockers_h
10 #include "mozilla/MozPromise.h"
11 #include "mozilla/ThreadSafety.h"
12 #include "nsTArray.h"
14 // FIXME: when bug 1760855 is fixed, it should not be required anymore
16 namespace mozilla::ipc {
18 /**
19 * AsyncBlockers provide a simple registration service that allows to suspend
20 * completion of a particular task until all registered entries have been
21 * cleared. This can be used to implement a similar service to
22 * nsAsyncShutdownService in processes where it wouldn't normally be available.
23 * This class is thread-safe.
25 class AsyncBlockers {
26 public:
27 AsyncBlockers()
28 : mLock("AsyncRegistrar"),
29 mPromise(new GenericPromise::Private(__func__)) {}
30 void Register(void* aBlocker) {
31 MutexAutoLock lock(mLock);
32 mBlockers.InsertElementSorted(aBlocker);
34 void Deregister(void* aBlocker) {
35 MutexAutoLock lock(mLock);
36 MOZ_ASSERT(mBlockers.ContainsSorted(aBlocker));
37 MOZ_ALWAYS_TRUE(mBlockers.RemoveElementSorted(aBlocker));
38 MaybeResolve();
40 RefPtr<GenericPromise> WaitUntilClear(uint32_t aTimeOutInMs = 0) {
42 MutexAutoLock lock(mLock);
43 MaybeResolve();
46 if (aTimeOutInMs > 0) {
47 GetCurrentSerialEventTarget()->DelayedDispatch(
48 NS_NewRunnableFunction("AsyncBlockers::WaitUntilClear",
49 [promise = mPromise]() {
50 // The AsyncBlockers object may have been
51 // deleted by now and the object isn't
52 // refcounted (nor do we want it to be). We
53 // can unconditionally resolve the promise
54 // even it has already been resolved as
55 // MozPromise are thread-safe and will just
56 // ignore the action if already resolved.
57 promise->Resolve(true, __func__);
58 }),
59 aTimeOutInMs);
62 return mPromise;
65 virtual ~AsyncBlockers() { mPromise->Resolve(true, __func__); }
67 private:
68 void MaybeResolve() MOZ_REQUIRES(mLock) {
69 mLock.AssertCurrentThreadOwns();
70 if (!mBlockers.IsEmpty()) {
71 return;
73 mPromise->Resolve(true, __func__);
75 Mutex mLock;
76 nsTArray<void*> mBlockers MOZ_GUARDED_BY(mLock);
77 const RefPtr<GenericPromise::Private> mPromise;
80 } // namespace mozilla::ipc
82 #endif // mozilla_ipc_AsyncBlockers_h