@@ -75,12 +75,12 @@ impl FlowControl {
75
75
self . window_size > self . available
76
76
}
77
77
78
- pub fn claim_capacity ( & mut self , capacity : WindowSize ) {
79
- self . available -= capacity;
78
+ pub fn claim_capacity ( & mut self , capacity : WindowSize ) -> Result < ( ) , Reason > {
79
+ self . available . decrease_by ( capacity)
80
80
}
81
81
82
- pub fn assign_capacity ( & mut self , capacity : WindowSize ) {
83
- self . available += capacity;
82
+ pub fn assign_capacity ( & mut self , capacity : WindowSize ) -> Result < ( ) , Reason > {
83
+ self . available . increase_by ( capacity)
84
84
}
85
85
86
86
/// If a WINDOW_UPDATE frame should be sent, returns a positive number
@@ -136,36 +136,38 @@ impl FlowControl {
136
136
///
137
137
/// This is called after receiving a SETTINGS frame with a lower
138
138
/// INITIAL_WINDOW_SIZE value.
139
- pub fn dec_send_window ( & mut self , sz : WindowSize ) {
139
+ pub fn dec_send_window ( & mut self , sz : WindowSize ) -> Result < ( ) , Reason > {
140
140
tracing:: trace!(
141
141
"dec_window; sz={}; window={}, available={}" ,
142
142
sz,
143
143
self . window_size,
144
144
self . available
145
145
) ;
146
- // This should not be able to overflow `window_size` from the bottom.
147
- self . window_size -= sz;
146
+ // ~~This should not be able to overflow `window_size` from the bottom.~~ wrong. it can.
147
+ self . window_size . decrease_by ( sz) ?;
148
+ Ok ( ( ) )
148
149
}
149
150
150
151
/// Decrement the recv-side window size.
151
152
///
152
153
/// This is called after receiving a SETTINGS ACK frame with a lower
153
154
/// INITIAL_WINDOW_SIZE value.
154
- pub fn dec_recv_window ( & mut self , sz : WindowSize ) {
155
+ pub fn dec_recv_window ( & mut self , sz : WindowSize ) -> Result < ( ) , Reason > {
155
156
tracing:: trace!(
156
157
"dec_recv_window; sz={}; window={}, available={}" ,
157
158
sz,
158
159
self . window_size,
159
160
self . available
160
161
) ;
161
162
// This should not be able to overflow `window_size` from the bottom.
162
- self . window_size -= sz;
163
- self . available -= sz;
163
+ self . window_size . decrease_by ( sz) ?;
164
+ self . available . decrease_by ( sz) ?;
165
+ Ok ( ( ) )
164
166
}
165
167
166
168
/// Decrements the window reflecting data has actually been sent. The caller
167
169
/// must ensure that the window has capacity.
168
- pub fn send_data ( & mut self , sz : WindowSize ) {
170
+ pub fn send_data ( & mut self , sz : WindowSize ) -> Result < ( ) , Reason > {
169
171
tracing:: trace!(
170
172
"send_data; sz={}; window={}; available={}" ,
171
173
sz,
@@ -176,12 +178,13 @@ impl FlowControl {
176
178
// If send size is zero it's meaningless to update flow control window
177
179
if sz > 0 {
178
180
// Ensure that the argument is correct
179
- assert ! ( self . window_size >= sz as usize ) ;
181
+ assert ! ( self . window_size. 0 >= sz as i32 ) ;
180
182
181
183
// Update values
182
- self . window_size -= sz ;
183
- self . available -= sz ;
184
+ self . window_size . decrease_by ( sz ) ? ;
185
+ self . available . decrease_by ( sz ) ? ;
184
186
}
187
+ Ok ( ( ) )
185
188
}
186
189
}
187
190
@@ -208,6 +211,29 @@ impl Window {
208
211
assert ! ( self . 0 >= 0 , "negative Window" ) ;
209
212
self . 0 as WindowSize
210
213
}
214
+
215
+ pub fn decrease_by ( & mut self , other : WindowSize ) -> Result < ( ) , Reason > {
216
+ if let Some ( v) = self . 0 . checked_sub ( other as i32 ) {
217
+ self . 0 = v;
218
+ Ok ( ( ) )
219
+ } else {
220
+ Err ( Reason :: FLOW_CONTROL_ERROR )
221
+ }
222
+ }
223
+
224
+ pub fn increase_by ( & mut self , other : WindowSize ) -> Result < ( ) , Reason > {
225
+ let other = self . add ( other) ?;
226
+ self . 0 = other. 0 ;
227
+ Ok ( ( ) )
228
+ }
229
+
230
+ pub fn add ( & self , other : WindowSize ) -> Result < Self , Reason > {
231
+ if let Some ( v) = self . 0 . checked_add ( other as i32 ) {
232
+ Ok ( Self ( v) )
233
+ } else {
234
+ Err ( Reason :: FLOW_CONTROL_ERROR )
235
+ }
236
+ }
211
237
}
212
238
213
239
impl PartialEq < usize > for Window {
@@ -230,25 +256,6 @@ impl PartialOrd<usize> for Window {
230
256
}
231
257
}
232
258
233
- impl :: std:: ops:: SubAssign < WindowSize > for Window {
234
- fn sub_assign ( & mut self , other : WindowSize ) {
235
- self . 0 -= other as i32 ;
236
- }
237
- }
238
-
239
- impl :: std:: ops:: Add < WindowSize > for Window {
240
- type Output = Self ;
241
- fn add ( self , other : WindowSize ) -> Self :: Output {
242
- Window ( self . 0 + other as i32 )
243
- }
244
- }
245
-
246
- impl :: std:: ops:: AddAssign < WindowSize > for Window {
247
- fn add_assign ( & mut self , other : WindowSize ) {
248
- self . 0 += other as i32 ;
249
- }
250
- }
251
-
252
259
impl fmt:: Display for Window {
253
260
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
254
261
fmt:: Display :: fmt ( & self . 0 , f)
0 commit comments