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