Implement ‘Connection::send_streams()’

This allows users to know when all data has been acknowledged.
This commit is contained in:
Demi M. Obenour
2020-03-07 14:56:50 -05:00
committed by Benjamin Saunders
parent 6cca808d14
commit 4bba80b673
3 changed files with 28 additions and 0 deletions
+5
View File
@@ -2708,6 +2708,11 @@ where
Some(id)
}
/// The number of streams that may have unacknowledged data.
pub fn send_streams(&self) -> usize {
self.streams.send_streams()
}
/// Finish a send stream, signalling that no more data will be sent
pub fn finish(&mut self, id: StreamId) -> Result<(), FinishError> {
let ss = self
+12
View File
@@ -21,6 +21,8 @@ pub(crate) struct Streams {
pub next_remote: [u64; 2],
// Next to report to the application, once opened
next_reported_remote: [u64; 2],
// Outbound streams
send_streams: usize,
}
impl Streams {
@@ -33,6 +35,7 @@ impl Streams {
max_remote: [max_remote_bi, max_remote_uni],
next_remote: [0, 0],
next_reported_remote: [0, 0],
send_streams: 0,
};
for dir in Dir::iter() {
@@ -52,9 +55,14 @@ impl Streams {
self.next[dir as usize] += 1;
let id = StreamId::new(side, dir, self.next[dir as usize] - 1);
self.insert(false, id);
self.send_streams += 1;
Some(id)
}
pub fn send_streams(&self) -> usize {
self.send_streams
}
pub fn alloc_remote_stream(&mut self, side: Side, dir: Dir) {
self.max_remote[dir as usize] += 1;
let id = StreamId::new(!side, dir, self.max_remote[dir as usize] - 1);
@@ -67,6 +75,9 @@ impl Streams {
}
let x = self.next_reported_remote[dir as usize];
self.next_reported_remote[dir as usize] = x + 1;
if dir == Dir::Bi {
self.send_streams += 1;
}
Some(StreamId::new(!side, dir, x))
}
@@ -162,6 +173,7 @@ impl Streams {
hash_map::Entry::Vacant(_) => {}
hash_map::Entry::Occupied(e) => {
if e.get().is_closed() {
self.send_streams -= 1;
e.remove_entry();
}
}
+11
View File
@@ -191,6 +191,7 @@ fn finish_stream_simple() {
const MSG: &[u8] = b"hello";
pair.client_conn_mut(client_ch).write(s, MSG).unwrap();
assert_eq!(pair.client_conn_mut(client_ch).send_streams(), 1);
pair.client_conn_mut(client_ch).finish(s).unwrap();
pair.drive();
@@ -199,10 +200,14 @@ fn finish_stream_simple() {
Some(Event::StreamFinished { stream, stop_reason: None }) if stream == s
);
assert_matches!(pair.client_conn_mut(client_ch).poll(), None);
assert_eq!(pair.client_conn_mut(client_ch).send_streams(), 0);
assert_eq!(pair.server_conn_mut(client_ch).send_streams(), 0);
assert_matches!(
pair.server_conn_mut(server_ch).poll(),
Some(Event::StreamOpened { dir: Dir::Uni })
);
// Receive-only streams do not get `StreamFinished` events
assert_eq!(pair.server_conn_mut(client_ch).send_streams(), 0);
assert_matches!(pair.server_conn_mut(server_ch).accept(Dir::Uni), Some(stream) if stream == s);
assert_matches!(pair.server_conn_mut(server_ch).poll(), None);
assert_matches!(
@@ -909,7 +914,9 @@ fn stop_opens_bidi() {
let _guard = subscribe();
let mut pair = Pair::default();
let (client_conn, server_conn) = pair.connect();
assert_eq!(pair.client_conn_mut(client_conn).send_streams(), 0);
let s = pair.client_conn_mut(client_conn).open(Dir::Bi).unwrap();
assert_eq!(pair.client_conn_mut(client_conn).send_streams(), 1);
const ERROR: VarInt = VarInt(42);
pair.client
.connections
@@ -923,7 +930,9 @@ fn stop_opens_bidi() {
pair.server_conn_mut(server_conn).poll(),
Some(Event::StreamOpened { dir: Dir::Bi })
);
assert_eq!(pair.server_conn_mut(client_conn).send_streams(), 0);
assert_matches!(pair.server_conn_mut(server_conn).accept(Dir::Bi), Some(stream) if stream == s);
assert_eq!(pair.server_conn_mut(client_conn).send_streams(), 1);
assert_matches!(
pair.server_conn_mut(server_conn).read_unordered(s),
Err(ReadError::Blocked)
@@ -932,6 +941,8 @@ fn stop_opens_bidi() {
pair.server_conn_mut(server_conn).write(s, b"foo"),
Err(WriteError::Stopped(ERROR))
);
assert_eq!(pair.server_conn_mut(client_conn).send_streams(), 0);
assert_matches!(pair.server_conn_mut(server_conn).poll(), None);
}
#[test]