flow.go raw

   1  // Copyright 2014 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // Flow control
   6  
   7  package http2
   8  
   9  // inflowMinRefresh is the minimum number of bytes we'll send for a
  10  // flow control window update.
  11  const inflowMinRefresh = 4 << 10
  12  
  13  // inflow accounts for an inbound flow control window.
  14  // It tracks both the latest window sent to the peer (used for enforcement)
  15  // and the accumulated unsent window.
  16  type inflow struct {
  17  	avail  int32
  18  	unsent int32
  19  }
  20  
  21  // init sets the initial window.
  22  func (f *inflow) init(n int32) {
  23  	f.avail = n
  24  }
  25  
  26  // add adds n bytes to the window, with a maximum window size of max,
  27  // indicating that the peer can now send us more data.
  28  // For example, the user read from a {Request,Response} body and consumed
  29  // some of the buffered data, so the peer can now send more.
  30  // It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer.
  31  // Window updates are accumulated and sent when the unsent capacity
  32  // is at least inflowMinRefresh or will at least double the peer's available window.
  33  func (f *inflow) add(n int) (connAdd int32) {
  34  	if n < 0 {
  35  		panic("negative update")
  36  	}
  37  	unsent := int64(f.unsent) + int64(n)
  38  	// "A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets."
  39  	// RFC 7540 Section 6.9.1.
  40  	const maxWindow = 1<<31 - 1
  41  	if unsent+int64(f.avail) > maxWindow {
  42  		panic("flow control update exceeds maximum window size")
  43  	}
  44  	f.unsent = int32(unsent)
  45  	if f.unsent < inflowMinRefresh && f.unsent < f.avail {
  46  		// If there aren't at least inflowMinRefresh bytes of window to send,
  47  		// and this update won't at least double the window, buffer the update for later.
  48  		return 0
  49  	}
  50  	f.avail += f.unsent
  51  	f.unsent = 0
  52  	return int32(unsent)
  53  }
  54  
  55  // take attempts to take n bytes from the peer's flow control window.
  56  // It reports whether the window has available capacity.
  57  func (f *inflow) take(n uint32) bool {
  58  	if n > uint32(f.avail) {
  59  		return false
  60  	}
  61  	f.avail -= int32(n)
  62  	return true
  63  }
  64  
  65  // takeInflows attempts to take n bytes from two inflows,
  66  // typically connection-level and stream-level flows.
  67  // It reports whether both windows have available capacity.
  68  func takeInflows(f1, f2 *inflow, n uint32) bool {
  69  	if n > uint32(f1.avail) || n > uint32(f2.avail) {
  70  		return false
  71  	}
  72  	f1.avail -= int32(n)
  73  	f2.avail -= int32(n)
  74  	return true
  75  }
  76  
  77  // outflow is the outbound flow control window's size.
  78  type outflow struct {
  79  	_ incomparable
  80  
  81  	// n is the number of DATA bytes we're allowed to send.
  82  	// An outflow is kept both on a conn and a per-stream.
  83  	n int32
  84  
  85  	// conn points to the shared connection-level outflow that is
  86  	// shared by all streams on that conn. It is nil for the outflow
  87  	// that's on the conn directly.
  88  	conn *outflow
  89  }
  90  
  91  func (f *outflow) setConnFlow(cf *outflow) { f.conn = cf }
  92  
  93  func (f *outflow) available() int32 {
  94  	n := f.n
  95  	if f.conn != nil && f.conn.n < n {
  96  		n = f.conn.n
  97  	}
  98  	return n
  99  }
 100  
 101  func (f *outflow) take(n int32) {
 102  	if n > f.available() {
 103  		panic("internal error: took too much")
 104  	}
 105  	f.n -= n
 106  	if f.conn != nil {
 107  		f.conn.n -= n
 108  	}
 109  }
 110  
 111  // add adds n bytes (positive or negative) to the flow control window.
 112  // It returns false if the sum would exceed 2^31-1.
 113  func (f *outflow) add(n int32) bool {
 114  	sum := f.n + n
 115  	if (sum > n) == (f.n > 0) {
 116  		f.n = sum
 117  		return true
 118  	}
 119  	return false
 120  }
 121