proxygen
Window.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
13 
14 #include <glog/logging.h>
15 #include <limits>
16 
17 namespace proxygen {
18 
20  CHECK(setCapacity(capacity));
21 }
22 
24  return capacity_ - outstanding_;
25 }
26 
28  auto size = getSize();
29  return size > 0 ? size : 0;
30 }
31 
33  // This conversion is safe since we always ensure capacity_ > 0
34  return static_cast<uint32_t>(capacity_);
35 }
36 
38  return outstanding_ < 0 ? 0 : outstanding_;
39 }
40 
41 bool Window::reserve(const uint32_t amount, bool strict) {
42  if (amount > std::numeric_limits<int32_t>::max()) {
43  VLOG(3) << "Cannot shrink window by more than 2^31 - 1. "
44  << "Attempted decrement of " << amount;
45  return false;
46  }
48  static_cast<int32_t>(amount);
49  if (outstanding_ > 0 && limit < outstanding_) {
50  VLOG(3) << "Overflow detected. Window change failed.";
51  return false;
52  }
53  const int32_t newOutstanding = outstanding_ + amount;
54  if (strict && newOutstanding > capacity_) {
55  VLOG(3) << "Outstanding bytes (" << newOutstanding << ") exceeded "
56  << "window capacity (" << capacity_ << ")";
57  return false;
58  }
59  outstanding_ = newOutstanding;
60  return true;
61 }
62 
63 bool Window::free(const uint32_t amount) {
64  if (amount > std::numeric_limits<int32_t>::max()) {
65  VLOG(3) << "Cannot expand window by more than 2^31 - 1. "
66  << "Attempted increment of " << amount;
67  return false;
68  }
70  static_cast<int32_t>(amount);
71  if (outstanding_ < 0 && limit > outstanding_) {
72  VLOG(3) << "Underflow detected. Window change failed.";
73  return false;
74  }
75  const int32_t newOutstanding = outstanding_ - amount;
76  if (newOutstanding < capacity_ - std::numeric_limits<int32_t>::max()) {
77  VLOG(3) << "Window exceeded 2^31 - 1. Window change failed.";
78  return false;
79  }
80  outstanding_ = newOutstanding;
81  return true;
82 }
83 
84 bool Window::setCapacity(const uint32_t capacity) {
85  if (capacity > std::numeric_limits<int32_t>::max()) {
86  VLOG(3) << "Cannot set initial window > 2^31 -1.";
87  return false;
88  }
89 
90  const int32_t diff = static_cast<int32_t>(capacity) - capacity_;
91  if (diff > 0) {
92  const int32_t size = getSize();
93  if (size > 0 && diff > (std::numeric_limits<int32_t>::max() - size)) {
94  VLOG(3) << "Increasing the capacity overflowed the window";
95  return false;
96  }
97  }
98 
99  capacity_ = static_cast<int32_t>(capacity);
100  return true;
101 }
102 
103 }
int32_t outstanding_
Definition: Window.h:80
uint32_t getCapacity() const
Definition: Window.cpp:32
LogLevel max
Definition: LogLevel.cpp:31
uint32_t getOutstanding() const
Definition: Window.cpp:37
int32_t getSize() const
Definition: Window.cpp:23
bool reserve(uint32_t amount, bool strict=true)
Definition: Window.cpp:41
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
LogLevel min
Definition: LogLevel.cpp:30
Window(uint32_t capacity)
Definition: Window.cpp:19
uint64_t diff(uint64_t a, uint64_t b)
Definition: FutexTest.cpp:135
bool setCapacity(uint32_t capacity)
Definition: Window.cpp:84
int32_t capacity_
Definition: Window.h:81
bool free(uint32_t amount)
Definition: Window.cpp:63
uint32_t getNonNegativeSize() const
Definition: Window.cpp:27