Fix packet buffer enqueue logic error
The size of the contiguous window should be prioritized over the size of the contiguous window if padding were added. For example, given the following packet buffer: 1 2 3 |---|----|------| If 2 is used and 1 and 3 are empty, enqueing a buffer of size 4 should be placed in contiguous window 3 and the size of 1 should not cause any issues in enqueue. Closes: #247 Approved by: whitequark
This commit is contained in:
parent
3d141489a2
commit
276acfb7ef
|
@ -84,13 +84,21 @@ impl<'a, 'b, H> PacketBuffer<'a, 'b, H> {
|
|||
let window = self.payload_ring.window();
|
||||
let contig_window = self.payload_ring.contiguous_window();
|
||||
|
||||
if window < size || (window != contig_window && window - contig_window < size) {
|
||||
if window < size {
|
||||
return Err(Error::Exhausted)
|
||||
}
|
||||
|
||||
if contig_window < size {
|
||||
*self.metadata_ring.enqueue_one()? = PacketMetadata::padding(size);
|
||||
self.payload_ring.enqueue_many(size);
|
||||
} else if contig_window < size {
|
||||
if window - contig_window < size {
|
||||
// The buffer length is larger than the current contiguous window
|
||||
// and is larger than the contiguous window will be after adding
|
||||
// the padding necessary to circle around to the beginning of the
|
||||
// ring buffer.
|
||||
return Err(Error::Exhausted)
|
||||
} else {
|
||||
// Add padding to the end of the ring buffer so that the
|
||||
// contiguous window is at the beginning of the ring buffer.
|
||||
*self.metadata_ring.enqueue_one()? = PacketMetadata::padding(size);
|
||||
self.payload_ring.enqueue_many(size);
|
||||
}
|
||||
}
|
||||
|
||||
*self.metadata_ring.enqueue_one()? = PacketMetadata::packet(size, header);
|
||||
|
@ -244,4 +252,12 @@ mod test {
|
|||
let mut buffer = buffer();
|
||||
assert_eq!(buffer.enqueue(32, ()), Err(Error::Truncated));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contig_window_prioritized() {
|
||||
let mut buffer = buffer();
|
||||
assert!(buffer.enqueue(4, ()).is_ok());
|
||||
assert!(buffer.dequeue().is_ok());
|
||||
assert!(buffer.enqueue(5, ()).is_ok());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue