Bug 1867190 - Initialise the PHC allocate delay later r=glandium
[gecko.git] / xpcom / threads / WinHandleWatcher.h
blobeb1e1c0245a05aa2505cee95e02f9070f7157f7b
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 WinHandleWatcher_h__
8 #define WinHandleWatcher_h__
10 #include <minwindef.h>
12 #include "mozilla/AlreadyAddRefed.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/UniquePtr.h"
16 #include "nsIEventTarget.h"
17 #include "nsIRunnable.h"
18 #include "nsIThread.h"
19 #include "nsThreadUtils.h"
21 namespace mozilla {
22 ///////////////////////////////////////////////////////////////////////
23 // HandleWatcher
25 // Enqueues a task onto an event target when a watched Win32 synchronization
26 // object [1] enters the signaled state.
28 // The HandleWatcher must be stopped before either it or the synchronization
29 // object is destroyed.
31 //////
33 // Example of use:
35 // ```
36 // class MyClass {
37 // /* ... */
39 // HANDLE CreateThing();
40 // void OnComplete();
41 // public:
42 // void Fire() {
43 // mHandle.set(CreateThing());
44 // mWatcher.Watch(
45 // mHandle.get(), NS_GetCurrentThread(), // (or any other thread)
46 // NS_NewRunnableFunction("OnComplete", [this] { OnComplete(); }));
47 // }
49 // ~MyClass() { mWatcher.Stop(); }
51 // HandleWatcher mWatcher;
52 // HandlePtr mHandle; // calls ::CloseHandle() on destruction
53 // };
54 // ```
56 // Note: this example demonstrates why an explicit `Stop()` is necessary in
57 // MyClass's destructor. Without it, the `HandlePtr` would destroy the HANDLE --
58 // and possibly whatever other data `OnComplete()` depends on -- before the
59 // watch was stopped!
61 // Rather than make code correctness silently dependent on member object order,
62 // we require that HandleWatcher already be stopped at its destruction time.
63 // (This does not guarantee correctness, as the task may still reference a
64 // partially-destroyed transitive owner; but, short of RIIR, a guarantee of
65 // correctness is probably not possible here.)
67 //////
69 // [1]https://learn.microsoft.com/en-us/windows/win32/sync/synchronization-objects
70 class HandleWatcher {
71 public:
72 class Impl;
74 HandleWatcher();
75 ~HandleWatcher();
77 HandleWatcher(HandleWatcher const&) = delete;
78 HandleWatcher& operator=(HandleWatcher const&) = delete;
80 HandleWatcher(HandleWatcher&&) noexcept;
81 HandleWatcher& operator=(HandleWatcher&&) noexcept;
83 // Watches the given Win32 HANDLE, which must be a synchronization object. As
84 // soon as the HANDLE is signaled, posts `aRunnable` to `aTarget`.
86 // `aHandle` is merely borrowed for the duration of the watch: the
87 // HandleWatcher does not attempt to close it, and its lifetime must exceed
88 // that of the watch.
90 // If the watch is stopped for any reason other than completion, `aRunnable`
91 // is released immediately, on the same thread from which the Watch was
92 // stopped.
94 // The watch is stopped when any of the following occurs:
95 // * `Stop()` is called.
96 // * `Watch()` is called again, even without an intervening `Stop()`.
97 // * This object is destroyed.
98 // * `aTarget` shuts down.
99 // * `aHandle` becomes signaled.
101 void Watch(HANDLE aHandle, nsIEventTarget* aTarget,
102 already_AddRefed<nsIRunnable> aRunnable);
104 // Cancels the current watch, if any.
106 // Idempotent. Thread-safe with respect to other calls of `Stop()`.
107 void Stop();
109 // Potentially racy. Only intended for tests.
110 bool IsStopped();
112 private:
113 RefPtr<Impl> mImpl;
115 } // namespace mozilla
117 #endif // WinHandleWatcher_h__