1 // Copyright 2022 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_ 6 #define QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_ 7 8 #include <cstdint> 9 #include <memory> 10 11 #include "absl/base/attributes.h" 12 #include "quiche/quic/core/io/socket.h" 13 #include "quiche/quic/core/quic_alarm_factory.h" 14 #include "quiche/quic/core/quic_clock.h" 15 16 namespace quic { 17 18 // A bitmask indicating a set of I/O events. 19 using QuicSocketEventMask = uint8_t; 20 inline constexpr QuicSocketEventMask kSocketEventReadable = 0x01; 21 inline constexpr QuicSocketEventMask kSocketEventWritable = 0x02; 22 inline constexpr QuicSocketEventMask kSocketEventError = 0x04; 23 24 class QuicEventLoop; 25 26 // A listener associated with a file descriptor. 27 class QuicSocketEventListener { 28 public: 29 virtual ~QuicSocketEventListener() = default; 30 31 virtual void OnSocketEvent(QuicEventLoop* event_loop, SocketFd fd, 32 QuicSocketEventMask events) = 0; 33 }; 34 35 // An abstraction for an event loop that can handle alarms and notify the 36 // listener about I/O events occuring to the registered UDP sockets. 37 // 38 // Note on error handling: while most of the methods below return a boolean to 39 // indicate whether the operation has succeeded or not, some will QUIC_BUG 40 // instead. 41 class QuicEventLoop { 42 public: 43 virtual ~QuicEventLoop() = default; 44 45 // Indicates whether the event loop implementation supports edge-triggered 46 // notifications. If true, all of the events are permanent and are notified 47 // as long as they are registered. If false, whenever an event is triggered, 48 // the event registration is unset and has to be re-armed using RearmSocket(). 49 virtual bool SupportsEdgeTriggered() const = 0; 50 51 // Watches for all of the requested |events| that occur on the |fd| and 52 // notifies the |listener| about them. |fd| must not be already registered; 53 // if it is, the function returns false. The |listener| must be alive for as 54 // long as it is registered. 55 virtual ABSL_MUST_USE_RESULT bool RegisterSocket( 56 SocketFd fd, QuicSocketEventMask events, 57 QuicSocketEventListener* listener) = 0; 58 // Removes the listener associated with |fd|. Returns false if the listener 59 // is not found. 60 virtual ABSL_MUST_USE_RESULT bool UnregisterSocket(SocketFd fd) = 0; 61 // Adds |events| to the list of the listened events for |fd|, given that |fd| 62 // is already registered. Must be only called if SupportsEdgeTriggered() is 63 // false. 64 virtual ABSL_MUST_USE_RESULT bool RearmSocket(SocketFd fd, 65 QuicSocketEventMask events) = 0; 66 // Causes the |fd| to be notified of |events| on the next event loop iteration 67 // even if none of the specified events has happened. 68 virtual ABSL_MUST_USE_RESULT bool ArtificiallyNotifyEvent( 69 SocketFd fd, QuicSocketEventMask events) = 0; 70 71 // Runs a single iteration of the event loop. The iteration will run for at 72 // most |default_timeout|. 73 virtual void RunEventLoopOnce(QuicTime::Delta default_timeout) = 0; 74 75 // Returns an alarm factory that allows alarms to be scheduled on this event 76 // loop. 77 virtual std::unique_ptr<QuicAlarmFactory> CreateAlarmFactory() = 0; 78 79 // Returns the clock that is used by the alarm factory that the event loop 80 // provides. 81 virtual const QuicClock* GetClock() = 0; 82 }; 83 84 // A factory object for the event loop. Every implementation is expected to have 85 // a static singleton instance. 86 class QuicEventLoopFactory { 87 public: ~QuicEventLoopFactory()88 virtual ~QuicEventLoopFactory() {} 89 90 // Creates an event loop. Note that |clock| may be ignored if the event loop 91 // implementation uses its own clock internally. 92 virtual std::unique_ptr<QuicEventLoop> Create(QuicClock* clock) = 0; 93 94 // A human-readable name of the event loop implementation used in diagnostics 95 // output. 96 virtual std::string GetName() const = 0; 97 }; 98 99 } // namespace quic 100 101 #endif // QUICHE_QUIC_IO_QUIC_EVENT_LOOP_H_ 102