xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_alarm.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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_CORE_QUIC_ALARM_H_
6 #define QUICHE_QUIC_CORE_QUIC_ALARM_H_
7 
8 #include "quiche/quic/core/quic_arena_scoped_ptr.h"
9 #include "quiche/quic/core/quic_connection_context.h"
10 #include "quiche/quic/core/quic_time.h"
11 #include "quiche/quic/platform/api/quic_export.h"
12 
13 namespace quic {
14 
15 // Abstract class which represents an alarm which will go off at a
16 // scheduled time, and execute the |OnAlarm| method of the delegate.
17 // An alarm may be cancelled, in which case it may or may not be
18 // removed from the underlying scheduling system, but in either case
19 // the task will not be executed.
20 class QUICHE_EXPORT QuicAlarm {
21  public:
22   class QUICHE_EXPORT Delegate {
23    public:
~Delegate()24     virtual ~Delegate() {}
25 
26     // If the alarm belongs to a single QuicConnection, return the corresponding
27     // QuicConnection.context_. Note the context_ is the first member of
28     // QuicConnection, so it should outlive the delegate.
29     // Otherwise return nullptr.
30     // The OnAlarm function will be called under the connection context, if any.
31     virtual QuicConnectionContext* GetConnectionContext() = 0;
32 
33     // Invoked when the alarm fires.
34     virtual void OnAlarm() = 0;
35   };
36 
37   // DelegateWithContext is a Delegate with a QuicConnectionContext* stored as a
38   // member variable.
39   class QUICHE_EXPORT DelegateWithContext : public Delegate {
40    public:
DelegateWithContext(QuicConnectionContext * context)41     explicit DelegateWithContext(QuicConnectionContext* context)
42         : context_(context) {}
~DelegateWithContext()43     ~DelegateWithContext() override {}
GetConnectionContext()44     QuicConnectionContext* GetConnectionContext() override { return context_; }
45 
46    private:
47     QuicConnectionContext* context_;
48   };
49 
50   // DelegateWithoutContext is a Delegate that does not have a corresponding
51   // context. Typically this means one object of the child class deals with many
52   // connections.
53   class QUICHE_EXPORT DelegateWithoutContext : public Delegate {
54    public:
~DelegateWithoutContext()55     ~DelegateWithoutContext() override {}
GetConnectionContext()56     QuicConnectionContext* GetConnectionContext() override { return nullptr; }
57   };
58 
59   explicit QuicAlarm(QuicArenaScopedPtr<Delegate> delegate);
60   QuicAlarm(const QuicAlarm&) = delete;
61   QuicAlarm& operator=(const QuicAlarm&) = delete;
62   virtual ~QuicAlarm();
63 
64   // Sets the alarm to fire at |deadline|.  Must not be called while
65   // the alarm is set.  To reschedule an alarm, call Cancel() first,
66   // then Set().
67   void Set(QuicTime new_deadline);
68 
69   // Both PermanentCancel() and Cancel() can cancel the alarm. If permanent,
70   // future calls to Set() and Update() will become no-op except emitting an
71   // error log.
72   //
73   // Both may be called repeatedly.  Does not guarantee that the underlying
74   // scheduling system will remove the alarm's associated task, but guarantees
75   // that the delegates OnAlarm method will not be called.
PermanentCancel()76   void PermanentCancel() { CancelInternal(true); }
Cancel()77   void Cancel() { CancelInternal(false); }
78 
79   // Return true if PermanentCancel() has been called.
80   bool IsPermanentlyCancelled() const;
81 
82   // Cancels and sets the alarm if the |deadline| is farther from the current
83   // deadline than |granularity|, and otherwise does nothing.  If |deadline| is
84   // not initialized, the alarm is cancelled.
85   void Update(QuicTime new_deadline, QuicTime::Delta granularity);
86 
87   // Returns true if |deadline_| has been set to a non-zero time.
88   bool IsSet() const;
89 
deadline()90   QuicTime deadline() const { return deadline_; }
91 
92  protected:
93   // Subclasses implement this method to perform the platform-specific
94   // scheduling of the alarm.  Is called from Set() or Fire(), after the
95   // deadline has been updated.
96   virtual void SetImpl() = 0;
97 
98   // Subclasses implement this method to perform the platform-specific
99   // cancelation of the alarm.
100   virtual void CancelImpl() = 0;
101 
102   // Subclasses implement this method to perform the platform-specific update of
103   // the alarm if there exists a more optimal implementation than calling
104   // CancelImpl() and SetImpl().
105   virtual void UpdateImpl();
106 
107   // Called by subclasses when the alarm fires.  Invokes the
108   // delegates |OnAlarm| if a delegate is set, and if the deadline
109   // has been exceeded.  Implementations which do not remove the
110   // alarm from the underlying scheduler on Cancel() may need to handle
111   // the situation where the task executes before the deadline has been
112   // reached, in which case they need to reschedule the task and must not
113   // call invoke this method.
114   void Fire();
115 
116  private:
117   void CancelInternal(bool permanent);
118 
119   QuicArenaScopedPtr<Delegate> delegate_;
120   QuicTime deadline_;
121 };
122 
123 }  // namespace quic
124 
125 #endif  // QUICHE_QUIC_CORE_QUIC_ALARM_H_
126