// We want highest to lowest, with None being higher than any value impl Ord for StreamOrder { fn cmp(&self, other: &Self) -> Ordering { ifself.sendorder.is_some() && other.sendorder.is_some() { // We want reverse order (high to low) when both values are specified.
other.sendorder.cmp(&self.sendorder)
} else { self.sendorder.cmp(&other.sendorder)
}
}
}
iflet (_, Some(rs)) = self.obtain_stream(*stream_id)? {
rs.send_flowc_update();
}
}
Frame::StreamsBlocked { .. } => {
stats.streams_blocked += 1; // We send an update every time we retire a stream. There is no need to // trigger flow updates here.
}
_ => return Err(Error::Internal), // This is not a stream frame.
}
Ok(())
}
/// # Errors /// When the stream does not exist or has no more data. /// /// # Returns /// `(bytes_read, fin)` where `fin` is `true` when the stream has ended. pubfn recv(&mutself, stream_id: StreamId, data: &mut [u8]) -> Res<(usize, bool)> { self.recv.read(stream_id, data)
}
/// # Errors /// When the stream does not exist. pubfn stop_sending(&mutself, stream_id: StreamId, err: AppError) -> Res<()> { self.recv.stop_sending(stream_id, err)
}
pubfn cleanup_closed_streams(&mutself) { // Remove ended send streams. If any were removed, bidi recv streams whose // send counterpart just disappeared may now be clearable too. self.recv.set_ended(self.send.remove_ended());
let (removed_bidi, removed_uni) = self.recv.remove_ended(&self.send, self.role);
// Send max_streams updates if we removed remote-initiated recv streams. // The updates will be send if any streams has been removed. self.remote_stream_limits[StreamType::BiDi].add_retired(removed_bidi); self.remote_stream_limits[StreamType::UniDi].add_retired(removed_uni);
}
fn ensure_created_if_remote(&mutself, stream_id: StreamId) -> Res<()> { if !stream_id.is_remote_initiated(self.role)
|| !self.remote_stream_limits[stream_id.stream_type()].is_new_stream(stream_id)?
{ // If it is not a remote stream and stream already exist. return Ok(());
}
let tp = match stream_id.stream_type() { // From the local perspective, this is a remote- originated BiDi stream. From // the remote perspective, this is a local-originated BiDi stream. Therefore, // look at the local transport parameters for the // INITIAL_MAX_STREAM_DATA_BIDI_REMOTE value to decide how much this endpoint // will allow its peer to send.
StreamType::BiDi => InitialMaxStreamDataBidiRemote,
StreamType::UniDi => InitialMaxStreamDataUni,
}; let recv_initial_max_stream_data = self.tps.borrow().local().get_integer(tp);
whileself.remote_stream_limits[stream_id.stream_type()].is_new_stream(stream_id)? { let next_stream_id = self.remote_stream_limits[stream_id.stream_type()].take_stream_id(); self.events.new_stream(next_stream_id);
if next_stream_id.is_bidi() { // From the local perspective, this is a remote- originated BiDi stream. // From the remote perspective, this is a local-originated BiDi stream. // Therefore, look at the remote's transport parameters for the // INITIAL_MAX_STREAM_DATA_BIDI_LOCAL value to decide how much this endpoint // is allowed to send its peer. let send_initial_max_stream_data = self
.tps
.borrow()
.remote()
.get_integer(InitialMaxStreamDataBidiLocal); self.send.insert(
next_stream_id,
SendStream::new(
next_stream_id,
send_initial_max_stream_data,
Rc::clone(&self.sender_fc), self.events.clone(),
),
);
}
}
Ok(())
}
/// Get or make a stream, and implicitly open additional streams as /// indicated by its stream id. /// # Errors /// When the stream cannot be created due to stream limits. /// When the stream is locally-initiated and has not existed. pubfn obtain_stream(
&mutself,
stream_id: StreamId,
) -> Res<(Option<&mut SendStream>, Option<&mut RecvStream>)> { self.ensure_created_if_remote(stream_id)?; let ss = self.send.get_mut(stream_id).ok(); let rs = self.recv.get_mut(stream_id).ok(); // If it is: // - neither a known send nor receive stream, // - and it must be locally initiated, // - and its index is larger than the local used stream limit, // then it is an illegal stream. if ss.is_none()
&& rs.is_none()
&& !stream_id.is_remote_initiated(self.role)
&& self.local_stream_limits[stream_id.stream_type()].used() <= stream_id.index()
{ return Err(Error::StreamState);
}
Ok((ss, rs))
}
/// # Errors /// When the stream does not exist. pubfn set_sendorder(&mutself, stream_id: StreamId, sendorder: Option<SendOrder>) -> Res<()> { self.send.set_sendorder(stream_id, sendorder)
}
/// # Errors /// When the stream does not exist. pubfn set_fairness(&mutself, stream_id: StreamId, fairness: bool) -> Res<()> { self.send.set_fairness(stream_id, fairness)
}
/// # Errors /// When a stream cannot be created, which might be temporary. pubfn stream_create(&mutself, st: StreamType) -> Res<StreamId> { matchself.local_stream_limits.take_stream_id(st) {
None => Err(Error::StreamLimit),
Some(new_id) => { let send_limit_tp = match st {
StreamType::UniDi => InitialMaxStreamDataUni,
StreamType::BiDi => InitialMaxStreamDataBidiRemote,
}; let send_limit = self.tps.borrow().remote().get_integer(send_limit_tp); let stream = SendStream::new(
new_id,
send_limit,
Rc::clone(&self.sender_fc), self.events.clone(),
); self.send.insert(new_id, stream);
if st == StreamType::BiDi { // From the local perspective, this is a local- originated BiDi stream. From the // remote perspective, this is a remote-originated BiDi stream. Therefore, look // at the local transport parameters for the // INITIAL_MAX_STREAM_DATA_BIDI_LOCAL value to decide how // much this endpoint will allow its peer to send. let recv_initial_max_stream_data = self
.tps
.borrow()
.local()
.get_integer(InitialMaxStreamDataBidiLocal);
// As a client, there are two sets of initial limits for sending stream data. // If the second limit is higher and streams have been created, then // ensure that streams are not blocked on the lower limit. ifself.role == Role::Client { self.send.update_initial_limit(self.tps.borrow().remote());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.