1 #ifndef QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_ 2 #define QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_ 3 4 #include <stddef.h> 5 #include <stdint.h> 6 7 #include <functional> 8 9 #include "quiche/common/platform/api/quiche_export.h" 10 11 namespace http2 { 12 namespace adapter { 13 14 namespace test { 15 class WindowManagerPeer; 16 } 17 18 // This class keeps track of a HTTP/2 flow control window, notifying a listener 19 // when a window update needs to be sent. This class is not thread-safe. 20 class QUICHE_EXPORT WindowManager { 21 public: 22 // A WindowUpdateListener is invoked when it is time to send a window update. 23 using WindowUpdateListener = std::function<void(int64_t)>; 24 25 // Invoked to determine whether to call the listener based on the window 26 // limit, window size, and delta that would be sent. 27 using ShouldWindowUpdateFn = 28 std::function<bool(int64_t limit, int64_t size, int64_t delta)>; 29 30 WindowManager(int64_t window_size_limit, WindowUpdateListener listener, 31 ShouldWindowUpdateFn should_window_update_fn = {}, 32 bool update_window_on_notify = true); 33 CurrentWindowSize()34 int64_t CurrentWindowSize() const { return window_; } WindowSizeLimit()35 int64_t WindowSizeLimit() const { return limit_; } 36 37 // Called when the window size limit is changed (typically via settings) but 38 // no window update should be sent. 39 void OnWindowSizeLimitChange(int64_t new_limit); 40 41 // Sets the window size limit to |new_limit| and notifies the listener to 42 // update as necessary. 43 void SetWindowSizeLimit(int64_t new_limit); 44 45 // Increments the running total of data bytes buffered. Returns true iff there 46 // is more window remaining. 47 bool MarkDataBuffered(int64_t bytes); 48 49 // Increments the running total of data bytes that have been flushed or 50 // dropped. Invokes the listener if the current window is smaller than some 51 // threshold and there is quota available to send. 52 void MarkDataFlushed(int64_t bytes); 53 54 // Convenience method, used when incoming data is immediately dropped or 55 // ignored. MarkWindowConsumed(int64_t bytes)56 void MarkWindowConsumed(int64_t bytes) { 57 MarkDataBuffered(bytes); 58 MarkDataFlushed(bytes); 59 } 60 61 // Increments the window size without affecting the limit. Useful if this end 62 // of a stream or connection issues a one-time WINDOW_UPDATE. IncreaseWindow(int64_t delta)63 void IncreaseWindow(int64_t delta) { window_ += delta; } 64 65 private: 66 friend class test::WindowManagerPeer; 67 68 void MaybeNotifyListener(); 69 70 // The upper bound on the flow control window. The GFE attempts to maintain a 71 // window of this size at the peer as data is proxied through. 72 int64_t limit_; 73 74 // The current flow control window that has not been advertised to the peer 75 // and not yet consumed. The peer can send this many bytes before becoming 76 // blocked. 77 int64_t window_; 78 79 // The amount of data already buffered, which should count against the flow 80 // control window upper bound. 81 int64_t buffered_; 82 83 WindowUpdateListener listener_; 84 85 ShouldWindowUpdateFn should_window_update_fn_; 86 87 bool update_window_on_notify_; 88 }; 89 90 } // namespace adapter 91 } // namespace http2 92 93 #endif // QUICHE_HTTP2_ADAPTER_WINDOW_MANAGER_H_ 94