diff --git a/src/seq_queue.rs b/src/seq_queue.rs index 28309ed..011b177 100644 --- a/src/seq_queue.rs +++ b/src/seq_queue.rs @@ -201,7 +201,7 @@ impl SeqEx { } /// If this returns `Ok` then `try_send` might succeed on next call. - pub fn receive_raw>( + pub fn receive_direct>( &mut self, seq_no: SeqNo, reply_no: Option, @@ -333,7 +333,7 @@ impl SeqEx { /// and since each fragment will be received in order it will be trivial for them to reconstruct /// the original file. #[must_use] - pub fn reply_raw(&mut self, reply_no: SeqNo, packet_data: SendData, current_time: i64) -> Option> { + pub fn reply_direct(&mut self, reply_no: SeqNo, packet_data: SendData, current_time: i64) -> Option> { if self.remove_reservation(reply_no) { let seq_no = self.next_send_seq_no; self.next_send_seq_no = self.next_send_seq_no.wrapping_add(1); @@ -356,14 +356,8 @@ impl SeqEx { None } } - pub fn ack_raw(&mut self, reply_no: SeqNo) -> Option { - if self.remove_reservation(reply_no) { - // Acks are only sent once. There is code in `receive_raw` to handle resending - // an ack in the event that the first one here was dropped by the network. - Some(reply_no) - } else { - None - } + pub fn ack_direct(&mut self, reply_no: SeqNo) -> bool { + self.remove_reservation(reply_no) } fn remove_reservation(&mut self, reply_no: SeqNo) -> bool { for i in 0..self.concurrent_replies_total { diff --git a/src/single_thread.rs b/src/single_thread.rs index a0190cd..f7b5846 100644 --- a/src/single_thread.rs +++ b/src/single_thread.rs @@ -12,16 +12,14 @@ impl<'a, TL: TransportLayer, SendData, RecvData, const CAP: usize> Rep /// and since each fragment will be received in order it will be trivial for them to reconstruct /// the original file. pub fn reply(mut self, packet_data: SendData) { - if let Some(Payload { seq_no, reply_no, data }) = self.0.reply_raw(self.2, packet_data, self.1.time()) { - self.1.send(seq_no, reply_no, data) - } + self.0.reply_raw(self.1, self.2, packet_data); core::mem::forget(self); } } impl<'a, TL: TransportLayer, SendData, RecvData, const CAP: usize> Drop for ReplyGuard<'a, TL, SendData, RecvData, CAP> { fn drop(&mut self) { - if let Some(reply_no) = self.0.ack_raw(self.2) { - self.1.send_ack(reply_no) + if self.0.ack_direct(self.2) { + self.1.send_ack(self.2) } } } @@ -33,6 +31,26 @@ pub struct RecvSuccess<'a, TL: TransportLayer, P: Into, Send } impl SeqEx { + /// If this returns `Ok` then `try_send` might succeed on next call. + pub fn receive_raw>( + &mut self, + mut app: impl TransportLayer, + seq_no: SeqNo, + reply_no: Option, + packet: P, + ) -> Result<(SeqNo, P, Option), Error> { + let ret = self.receive_direct(seq_no, reply_no, packet); + } + pub fn reply_raw(&mut self, mut app: impl TransportLayer, reply_no: SeqNo, packet_data: SendData) { + if let Some(Payload { seq_no, reply_no, data }) = self.reply_direct(reply_no, packet_data, app.time()) { + app.send(seq_no, reply_no, data) + } + } + pub fn ack_raw(&mut self, mut app: impl TransportLayer, reply_no: SeqNo) { + if self.ack_direct(reply_no) { + app.send_ack(reply_no) + } + } pub fn receive, P: Into>( &mut self, app: TL, @@ -40,7 +58,7 @@ impl SeqEx { reply_no: Option, packet: P, ) -> Result, Error> { - self.receive_raw(seq_no, reply_no, packet) + self.receive_raw(app, seq_no, reply_no, packet) .map(|(reply_no, packet, send_data)| RecvSuccess { guard: ReplyGuard(self, app, reply_no), packet, send_data }) } pub fn pump>(&mut self, app: TL) -> Result, Error> { diff --git a/src/sync.rs b/src/sync.rs index 040c6f0..33c23ef 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -7,7 +7,7 @@ use std::{ time::Instant, }; -use crate::{Error, SeqEx, SeqNo, TransportLayer, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP, Payload}; +use crate::{Error, SeqEx, SeqNo, TransportLayer, DEFAULT_INITIAL_SEQ_NO, DEFAULT_RESEND_INTERVAL_MS, DEFAULT_WINDOW_CAP}; pub struct SeqExSync { seq_ex: Mutex<(SeqEx, usize)>, @@ -25,24 +25,22 @@ impl<'a, TL: TransportLayer, SendData, RecvData, const CAP: usize> Rep /// The identifier will tell the remote peer which packets contain fragments of the file, /// and since each fragment will be received in order it will be trivial for them to reconstruct /// the original file. - pub fn reply(mut self, packet_data: SendData) { - self.reply_with(|_, _| packet_data) + pub fn reply(self, packet_data: SendData) { + let mut seq = self.origin.lock(); + seq.reply_raw(self.app.clone(), self.reply_no, packet_data); + core::mem::forget(self); } - pub fn reply_with(mut self, packet_data: impl FnOnce(SeqNo, SeqNo) -> SendData) { + pub fn reply_with(self, packet_data: impl FnOnce(SeqNo, SeqNo) -> SendData) { let mut seq = self.origin.lock(); let seq_no = seq.seq_no(); - if let Some(Payload { seq_no, reply_no, data }) = seq.reply_raw(self.reply_no, packet_data(seq_no, self.reply_no), self.app.time()) { - self.app.send(seq_no, reply_no, data) - } + seq.reply_raw(self.app.clone(), self.reply_no, packet_data(seq_no, self.reply_no)); core::mem::forget(self); } } impl<'a, TL: TransportLayer, SendData, RecvData, const CAP: usize> Drop for ReplyGuard<'a, TL, SendData, RecvData, CAP> { fn drop(&mut self) { let mut seq = self.origin.lock(); - if let Some(reply_no) = seq.ack_raw(self.reply_no) { - self.app.send_ack(reply_no) - } + seq.ack_raw(self.app.clone(), self.reply_no); } } @@ -82,16 +80,13 @@ impl SeqExSync { pub fn receive, P: Into>( &self, - mut app: TL, + app: TL, seq_no: SeqNo, reply_no: Option, packet: P, ) -> Result, Error> { let mut seq = self.seq_ex.lock().unwrap(); - let ret = seq.0.receive_raw(seq_no, reply_no, packet); - if let Err(Error::ResendAck(ack_no)) = ret { - app.send_ack(ack_no); - } + let ret = seq.0.receive_raw(app.clone(), seq_no, reply_no, packet); if seq.1 > 0 && ret.is_ok() { self.send_block.notify_one(); } @@ -126,30 +121,21 @@ impl SeqExSync { ReplyIter { origin: None, app, first: None } } } - pub fn try_send>(&self, mut app: TL, packet_data: SendData) -> Result<(), SendData> { + pub fn try_send>(&self, app: TL, packet_data: SendData) -> Result<(), SendData> { let mut seq = self.lock(); - let ret = seq.try_send(packet_data, app.time()); - if let Ok(Payload { seq_no, reply_no, data }) = ret { - app.send(seq_no, reply_no, data) - } - ret.map(|_| ()) + seq.try_send(app, packet_data) } fn send_inner>( &self, mut seq: MutexGuard<'_, (SeqEx, usize)>, - mut app: TL, + app: TL, mut packet_data: SendData, ) { - loop { - let ret = seq.0.try_send(packet_data, app.time()); - if let Err(p) = ret { - packet_data = p; - seq.1 += 1; - seq = self.send_block.wait(seq).unwrap(); - seq.1 -= 1; - } else if let Ok(Payload { seq_no, reply_no, data }) = ret { - app.send(seq_no, reply_no, data) - } + while let Err(p) = seq.0.try_send(app.clone(), packet_data) { + packet_data = p; + seq.1 += 1; + seq = self.send_block.wait(seq).unwrap(); + seq.1 -= 1; } } pub fn send>(&self, app: TL, packet_data: SendData) {