From c38446dd3b48e0cc8406f5169599045457f1228b Mon Sep 17 00:00:00 2001 From: Irene Zhang Date: Thu, 16 Nov 2023 01:20:00 +0000 Subject: [PATCH] [inetstack] Enhancement: Cancel pending ops --- src/rust/inetstack/protocols/tcp/queue.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/rust/inetstack/protocols/tcp/queue.rs b/src/rust/inetstack/protocols/tcp/queue.rs index 89b053b29..292911b1a 100644 --- a/src/rust/inetstack/protocols/tcp/queue.rs +++ b/src/rust/inetstack/protocols/tcp/queue.rs @@ -312,6 +312,7 @@ impl SharedTcpQueue { pub fn close(&mut self) -> Result, Fail> { self.state_machine.prepare(SocketOp::Close)?; + self.cancel_pending_ops(Fail::new(libc::ECANCELED, "This queue was closed")); let new_socket: Option> = match self.socket { // Closing an active socket. Socket::Established(ref mut socket) => { @@ -496,6 +497,16 @@ impl SharedTcpQueue { self.pending_ops.insert(handle.clone(), yielder_handle.clone()); } + /// Cancel all currently pending operations on this queue. If the operation is not complete and the coroutine has + /// yielded, wake the coroutine with an error. + fn cancel_pending_ops(&mut self, cause: Fail) { + for (handle, mut yielder_handle) in self.pending_ops.drain() { + if !handle.has_completed() { + yielder_handle.wake_with(Err(cause.clone())); + } + } + } + /// Generic function for spawning a control-path coroutine on [self]. fn do_generic_sync_control_path_call(&mut self, coroutine: F) -> Result where