mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-12 09:31:20 +00:00
[multistream-select] Require remaining negotiation data to be flushed. (#1781)
* Require remaining negotiation data to be flushed. There appears to still be an edge-case whereby the `remaining` data to send w.r.t. protocol negotiation to send is successfully written before a `poll_read` on a `Negotiated` stream, but where the subsequent `poll_flush()` is pending. Now `remaining` is empty and the next `poll_read()` will go straight to reading from the underlying I/O stream, despite the flush not having happened yet, which can lead to a form of deadlock during protocol negotiation. Rather than complicating the existing code further in order to accommodate for this case, it seems preferable to simplify the code by giving up on this optimisation that only affects the last negotiation protocol message sent by the "listener". So we give up on the ability to combine data sent by the "listener" immediately after protocol negotiation together with the final negotiation frame in the same transport-level frame/packet. * Update changelog. * Add missing comma.
This commit is contained in:
@ -289,23 +289,16 @@ impl<R> MessageIO<R> {
|
||||
MessageReader { inner: self.inner.into_reader() }
|
||||
}
|
||||
|
||||
/// Drops the [`MessageIO`] resource, yielding the underlying I/O stream
|
||||
/// together with the remaining write buffer containing the protocol
|
||||
/// negotiation frame data that has not yet been written to the I/O stream.
|
||||
///
|
||||
/// The returned remaining write buffer may be prepended to follow-up
|
||||
/// protocol data to send with a single `write`. Either way, if non-empty,
|
||||
/// the write buffer _must_ eventually be written to the I/O stream
|
||||
/// _before_ any follow-up data, in order for protocol negotiation to
|
||||
/// complete cleanly.
|
||||
/// Drops the [`MessageIO`] resource, yielding the underlying I/O stream.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the read buffer is not empty, meaning that an incoming
|
||||
/// protocol negotiation frame has been partially read. The read buffer
|
||||
/// is guaranteed to be empty whenever `MessageIO::poll` returned
|
||||
/// a message.
|
||||
pub fn into_inner(self) -> (R, BytesMut) {
|
||||
/// Panics if the read buffer or write buffer is not empty, meaning that an incoming
|
||||
/// protocol negotiation frame has been partially read or an outgoing frame
|
||||
/// has not yet been flushed. The read buffer is guaranteed to be empty whenever
|
||||
/// `MessageIO::poll` returned a message. The write buffer is guaranteed to be empty
|
||||
/// when the sink has been flushed.
|
||||
pub fn into_inner(self) -> R {
|
||||
self.inner.into_inner()
|
||||
}
|
||||
}
|
||||
@ -365,19 +358,14 @@ impl<R> MessageReader<R> {
|
||||
/// together with the remaining write buffer containing the protocol
|
||||
/// negotiation frame data that has not yet been written to the I/O stream.
|
||||
///
|
||||
/// The returned remaining write buffer may be prepended to follow-up
|
||||
/// protocol data to send with a single `write`. Either way, if non-empty,
|
||||
/// the write buffer _must_ eventually be written to the I/O stream
|
||||
/// _before_ any follow-up data, in order for protocol negotiation to
|
||||
/// complete cleanly.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the read buffer is not empty, meaning that an incoming
|
||||
/// protocol negotiation frame has been partially read. The read buffer
|
||||
/// is guaranteed to be empty whenever `MessageReader::poll` returned
|
||||
/// a message.
|
||||
pub fn into_inner(self) -> (R, BytesMut) {
|
||||
/// Panics if the read buffer or write buffer is not empty, meaning that either
|
||||
/// an incoming protocol negotiation frame has been partially read, or an
|
||||
/// outgoing frame has not yet been flushed. The read buffer is guaranteed to
|
||||
/// be empty whenever `MessageReader::poll` returned a message. The write
|
||||
/// buffer is guaranteed to be empty whenever the sink has been flushed.
|
||||
pub fn into_inner(self) -> R {
|
||||
self.inner.into_inner()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user