From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- ipc/chromium/src/base/message_pump_libevent.h | 181 ++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 ipc/chromium/src/base/message_pump_libevent.h (limited to 'ipc/chromium/src/base/message_pump_libevent.h') diff --git a/ipc/chromium/src/base/message_pump_libevent.h b/ipc/chromium/src/base/message_pump_libevent.h new file mode 100644 index 0000000000..b1a7d474b3 --- /dev/null +++ b/ipc/chromium/src/base/message_pump_libevent.h @@ -0,0 +1,181 @@ +/* -*- 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_MESSAGE_PUMP_LIBEVENT_H_ +#define BASE_MESSAGE_PUMP_LIBEVENT_H_ + +#include "base/message_pump.h" +#include "base/time.h" + +// Declare structs we need from libevent.h rather than including it +struct event_base; +struct event; + +namespace base { + +// Class to monitor sockets and issue callbacks when sockets are ready for I/O +// TODO(dkegel): add support for background file IO somehow +class MessagePumpLibevent : public MessagePump { + public: + // Object returned by WatchFileDescriptor to manage further watching. + class FileDescriptorWatcher { + public: + FileDescriptorWatcher(); + ~FileDescriptorWatcher(); // Implicitly calls StopWatchingFileDescriptor. + + // NOTE: These methods aren't called StartWatching()/StopWatching() to + // avoid confusion with the win32 ObjectWatcher class. + + // Stop watching the FD, always safe to call. No-op if there's nothing + // to do. + bool StopWatchingFileDescriptor(); + + private: + // Called by MessagePumpLibevent, ownership of |e| is transferred to this + // object. + void Init(event* e, bool is_persistent); + + // Used by MessagePumpLibevent to take ownership of event_. + event* ReleaseEvent(); + friend class MessagePumpLibevent; + + private: + bool is_persistent_; // false if this event is one-shot. + event* event_; + DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher); + }; + + // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of + // a File Descriptor. + class Watcher { + public: + virtual ~Watcher() {} + // Called from MessageLoop::Run when an FD can be read from/written to + // without blocking + virtual void OnFileCanReadWithoutBlocking(int fd) = 0; + virtual void OnFileCanWriteWithoutBlocking(int fd) = 0; + }; + + MessagePumpLibevent(); + + enum Mode { + WATCH_READ = 1 << 0, + WATCH_WRITE = 1 << 1, + WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE + }; + + // Have the current thread's message loop watch for a a situation in which + // reading/writing to the FD can be performed without Blocking. + // Callers must provide a preallocated FileDescriptorWatcher object which + // can later be used to manage the Lifetime of this event. + // If a FileDescriptorWatcher is passed in which is already attached to + // an event, then the effect is cumulative i.e. after the call |controller| + // will watch both the previous event and the new one. + // If an error occurs while calling this method in a cumulative fashion, the + // event previously attached to |controller| is aborted. + // Returns true on success. + // TODO(dkegel): switch to edge-triggered readiness notification + bool WatchFileDescriptor(int fd, bool persistent, Mode mode, + FileDescriptorWatcher* controller, + Watcher* delegate); + + // This is analagous to FileDescriptorWatcher above, which really is + // just a wrapper around libevent's |struct event|. This class acts + // as a sort of "scoped event watcher" in that it guarantees that + // when this class is out of scope, the signal-event it wraps is + // removed from libevent's guts. + // + // XXX/cjones: this isn't my favorite API, but preserving it in + // order to match code above + class SignalEvent { + friend class MessagePumpLibevent; + + public: + SignalEvent(); + ~SignalEvent(); // implicitly calls StopCatching() + + // Have libevent forget this event. + bool StopCatching(); + + private: + void Init(event* e); + event* ReleaseEvent(); + + event* event_; + + DISALLOW_COPY_AND_ASSIGN(SignalEvent); + }; + + class SignalWatcher { + public: + virtual ~SignalWatcher() {} + // Called from MessageLoop::Run when |sig| has been delivered to + // this process + virtual void OnSignal(int sig) = 0; + }; + + // Have the current thread's message loop catch the signal |sig|. + // Multiple watchers can catch the same signal; they're all notified + // upon its delivery. Callers must provide a preallocated + // SignalEvent object which can be used to manage the lifetime of + // this event. Returns true on success. + bool CatchSignal(int sig, SignalEvent* sigevent, SignalWatcher* delegate); + + // MessagePump methods: + virtual void Run(Delegate* delegate) override; + virtual void Quit() override; + virtual void ScheduleWork() override; + virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; + + protected: + virtual ~MessagePumpLibevent(); + + private: + // Risky part of constructor. Returns true on success. + bool Init(); + + // This flag is set to false when Run should return. + bool keep_running_; + + // This flag is set when inside Run. + bool in_run_; + + // The time at which we should call DoDelayedWork. + TimeTicks delayed_work_time_; + + // Libevent dispatcher. Watches all sockets registered with it, and sends + // readiness callbacks when a socket is ready for I/O. + event_base* event_base_; + + // Called by libevent to tell us a registered FD can be read/written to. + static void OnLibeventNotification(int fd, short flags, void* context); + + // Called by libevent upon receiving a signal + static void OnLibeventSignalNotification(int sig, short flags, void* context); + + // Unix pipe used to implement ScheduleWork() + // ... callback; called by libevent inside Run() when pipe is ready to read + static void OnWakeup(int socket, short flags, void* context); + // ... write end; ScheduleWork() writes a single byte to it + int wakeup_pipe_in_; + // ... read end; OnWakeup reads it and then breaks Run() out of its sleep + int wakeup_pipe_out_; + // ... libevent wrapper for read end + event* wakeup_event_; + + // Set to false when calling event_base_loop and to true when either of the + // OnWakeup, OnLibeventNotification or OnLibeventSignalNotification callbacks + // is called. + // Used to ensure our calls to profiler_thread_sleep and profiler_thread_wake + // are paired correctly. + static bool awake_; + + DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent); +}; + +} // namespace base + +#endif // BASE_MESSAGE_PUMP_LIBEVENT_H_ -- cgit v1.2.3