blob: cc4139227b806cb75547e03578a5d4d99e17ebee [file] [log] [blame]
// Copyright 2022 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 QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_
#define QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_
#include <cstdint>
#include <memory>
#include "absl/base/attributes.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_udp_socket.h"
namespace quic {
// A bitmask indicating a set of I/O events.
using QuicSocketEventMask = uint8_t;
inline constexpr QuicSocketEventMask kSocketEventReadable = 0x01;
inline constexpr QuicSocketEventMask kSocketEventWritable = 0x02;
inline constexpr QuicSocketEventMask kSocketEventError = 0x04;
class QuicEventLoop;
// A listener associated with a file descriptor.
class QUICHE_NO_EXPORT QuicSocketEventListener {
public:
virtual ~QuicSocketEventListener() = default;
virtual void OnSocketEvent(QuicEventLoop* event_loop, QuicUdpSocketFd fd,
QuicSocketEventMask events) = 0;
};
// An abstraction for an event loop that can handle alarms and notify the
// listener about I/O events occuring to the registered UDP sockets.
//
// Note on error handling: while most of the methods below return a boolean to
// indicate whether the operation has succeeded or not, some will QUIC_BUG
// instead.
class QUICHE_NO_EXPORT QuicEventLoop {
public:
virtual ~QuicEventLoop() = default;
// Indicates whether the event loop implementation supports edge-triggered
// notifications. If true, all of the events are permanent and are notified
// as long as they are registered. If false, whenever an event is triggered,
// the event registration is unset and has to be re-armed using RearmSocket().
virtual bool SupportsEdgeTriggered() const = 0;
// Watches for all of the requested |events| that occur on the |fd| and
// notifies the |listener| about them. |fd| must not be already registered;
// if it is, the function returns false. The |listener| must be alive for as
// long as it is registered.
virtual ABSL_MUST_USE_RESULT bool RegisterSocket(
QuicUdpSocketFd fd, QuicSocketEventMask events,
QuicSocketEventListener* listener) = 0;
// Removes the listener associated with |fd|. Returns false if the listener
// is not found.
virtual ABSL_MUST_USE_RESULT bool UnregisterSocket(QuicUdpSocketFd fd) = 0;
// Adds |events| to the list of the listened events for |fd|, given that |fd|
// is already registered. Must be only called if SupportsEdgeTriggered() is
// false.
virtual ABSL_MUST_USE_RESULT bool RearmSocket(QuicUdpSocketFd fd,
QuicSocketEventMask events) = 0;
// Causes the |fd| to be notified of |events| on the next event loop iteration
// even if none of the specified events has happened.
virtual ABSL_MUST_USE_RESULT bool ArtificiallyNotifyEvent(
QuicUdpSocketFd fd, QuicSocketEventMask events) = 0;
// Runs a single iteration of the event loop. The iteration will run for at
// most |default_timeout|.
virtual void RunEventLoopOnce(QuicTime::Delta default_timeout) = 0;
// Returns an alarm factory that allows alarms to be scheduled on this event
// loop. The factory is owned by the event loop.
virtual QuicAlarmFactory* GetAlarmFactory() = 0;
};
} // namespace quic
#endif // QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_