blob: ffe1a7f623e911bfa00401f25372ce544b3ddb55 [file] [log] [blame]
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_callbacks.h"
namespace http2 {
namespace adapter {
namespace test {
class WindowManagerPeer;
// This class keeps track of a HTTP/2 flow control window, notifying a listener
// when a window update needs to be sent. This class is not thread-safe.
class QUICHE_EXPORT WindowManager {
// A WindowUpdateListener is invoked when it is time to send a window update.
using WindowUpdateListener = quiche::MultiUseCallback<void(int64_t)>;
// Invoked to determine whether to call the listener based on the window
// limit, window size, and delta that would be sent.
using ShouldWindowUpdateFn = bool (*)(int64_t limit, int64_t size,
int64_t delta);
WindowManager(int64_t window_size_limit, WindowUpdateListener listener,
ShouldWindowUpdateFn should_window_update_fn = {},
bool update_window_on_notify = true);
int64_t CurrentWindowSize() const { return window_; }
int64_t WindowSizeLimit() const { return limit_; }
// Called when the window size limit is changed (typically via settings) but
// no window update should be sent.
void OnWindowSizeLimitChange(int64_t new_limit);
// Sets the window size limit to |new_limit| and notifies the listener to
// update as necessary.
void SetWindowSizeLimit(int64_t new_limit);
// Increments the running total of data bytes buffered. Returns true iff there
// is more window remaining.
bool MarkDataBuffered(int64_t bytes);
// Increments the running total of data bytes that have been flushed or
// dropped. Invokes the listener if the current window is smaller than some
// threshold and there is quota available to send.
void MarkDataFlushed(int64_t bytes);
// Convenience method, used when incoming data is immediately dropped or
// ignored.
void MarkWindowConsumed(int64_t bytes) {
// Increments the window size without affecting the limit. Useful if this end
// of a stream or connection issues a one-time WINDOW_UPDATE.
void IncreaseWindow(int64_t delta) { window_ += delta; }
friend class test::WindowManagerPeer;
void MaybeNotifyListener();
// The upper bound on the flow control window. The GFE attempts to maintain a
// window of this size at the peer as data is proxied through.
int64_t limit_;
// The current flow control window that has not been advertised to the peer
// and not yet consumed. The peer can send this many bytes before becoming
// blocked.
int64_t window_;
// The amount of data already buffered, which should count against the flow
// control window upper bound.
int64_t buffered_;
WindowUpdateListener listener_;
ShouldWindowUpdateFn should_window_update_fn_;
bool update_window_on_notify_;
} // namespace adapter
} // namespace http2