diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /ipc/chromium/src/base/object_watcher.h | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/chromium/src/base/object_watcher.h')
-rw-r--r-- | ipc/chromium/src/base/object_watcher.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ipc/chromium/src/base/object_watcher.h b/ipc/chromium/src/base/object_watcher.h new file mode 100644 index 0000000000..1e1b27aa46 --- /dev/null +++ b/ipc/chromium/src/base/object_watcher.h @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_OBJECT_WATCHER_H_ +#define BASE_OBJECT_WATCHER_H_ + +#include <windows.h> +#ifdef GetClassName +# undef GetClassName +#endif + +#include "base/message_loop.h" + +namespace base { + +// A class that provides a means to asynchronously wait for a Windows object to +// become signaled. It is an abstraction around RegisterWaitForSingleObject +// that provides a notification callback, OnObjectSignaled, that runs back on +// the origin thread (i.e., the thread that called StartWatching). +// +// This class acts like a smart pointer such that when it goes out-of-scope, +// UnregisterWaitEx is automatically called, and any in-flight notification is +// suppressed. +// +// Typical usage: +// +// ``` +// class MyClass : public base::ObjectWatcher::Delegate { +// public: +// void DoStuffWhenSignaled(HANDLE object) { +// watcher_.StartWatching(object, this); +// } +// virtual void OnObjectSignaled(HANDLE object) { +// // OK, time to do stuff! +// } +// private: +// base::ObjectWatcher watcher_; +// }; +// ``` +// +// In the above example, MyClass wants to "do stuff" when object becomes +// signaled. ObjectWatcher makes this task easy. When MyClass goes out of +// scope, the watcher_ will be destroyed, and there is no need to worry about +// OnObjectSignaled being called on a deleted MyClass pointer. Easy! +// +////// +// +// Mozilla/Gecko addendum: +// +// An undocumented (but runtime-asserted) requirement for the above is that +// `MyClass` must be strictly thread-affine. In particular, `StartWatching()` +// and `StopWatching()` -- including the implicit `StopWatching()` call in +// `~ObjectWatcher()` -- must always be called on the same thread and from +// within the same `MessageLoop`. +// +// (If this did not hold, `OnObjectSignaled()` might be called on one thread +// while `MyClass` is in the middle of being destroyed on another.) +// +// This condition cannot be guaranteed for potentially-asynchronously-destroyed +// classes, nor for their owned or shared subobjects, nor for anything which +// might be sent to a non-thread-affine task queue. +// +class ObjectWatcher : public MessageLoop::DestructionObserver { + public: + class Delegate { + public: + virtual ~Delegate() {} + // Called from the MessageLoop when a signaled object is detected. To + // continue watching the object, AddWatch must be called again. + virtual void OnObjectSignaled(HANDLE object) = 0; + }; + + ObjectWatcher(); + ~ObjectWatcher(); + + // When the object is signaled, the given delegate is notified on the thread + // where StartWatching is called. The ObjectWatcher is not responsible for + // deleting the delegate. + // + // Returns true if the watch was started. Otherwise, false is returned. + // + bool StartWatching(HANDLE object, Delegate* delegate); + + // Stops watching. Does nothing if the watch has already completed. If the + // watch is still active, then it is canceled, and the associated delegate is + // not notified. + // + // Returns true if the watch was canceled. Otherwise, false is returned. + // + bool StopWatching(); + + // Returns the handle of the object being watched, or NULL if the object + // watcher is stopped. + HANDLE GetWatchedObject(); + + private: + // Called on a background thread when done waiting. + static void CALLBACK DoneWaiting(void* param, BOOLEAN timed_out); + + // MessageLoop::DestructionObserver implementation: + virtual void WillDestroyCurrentMessageLoop(); + + // Internal state. + class Watch; + RefPtr<Watch> watch_; + + DISALLOW_COPY_AND_ASSIGN(ObjectWatcher); +}; + +} // namespace base + +#endif // BASE_OBJECT_WATCHER_H_ |