From e57b40fb559f5ab071ac796b61cf01a131dab652 Mon Sep 17 00:00:00 2001 From: "Valeriy V. Vorotyntsev" Date: Fri, 10 Apr 2026 20:09:37 +0300 Subject: [PATCH] Unblock DataCell::get*() as soon as the cell is closed Problem: `DataCell::get` on an empty cell remains blocked even after the cell is closed. Solution: check `if value.closed` inside the loop. --- src/cell/datacell.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/cell/datacell.rs b/src/cell/datacell.rs index ce815b1..e733beb 100644 --- a/src/cell/datacell.rs +++ b/src/cell/datacell.rs @@ -94,10 +94,10 @@ where /// Retrieves the data from the cell pub fn get(&self) -> Result

{ let mut value = self.inner.value.lock(); - if value.closed { - return Err(Error::ChannelClosed); - } loop { + if value.closed { + return Err(Error::ChannelClosed); + } if let Some(current) = value.current.take() { return Ok(current); } @@ -109,10 +109,10 @@ where /// Retrieves the data from the cell with the given timeout pub fn get_timeout(&self, timeout: Duration) -> Result

{ let mut value = self.inner.value.lock(); - if value.closed { - return Err(Error::ChannelClosed); - } loop { + if value.closed { + return Err(Error::ChannelClosed); + } if let Some(current) = value.current.take() { return Ok(current); } @@ -180,6 +180,19 @@ mod test { handle.join().unwrap(); } + #[test] + fn test_datacell_close_empty() { + let cell: DataCell = DataCell::new(); + let cell2 = cell.clone(); + let handle = thread::spawn( + move || cell2.get(), // blocks until the cell is closed + ); + thread::sleep(Duration::from_millis(100)); + cell.close(); + assert!(matches!(handle.join().unwrap(), Err(Error::ChannelClosed))); + assert!(matches!(cell.get().unwrap_err(), Error::ChannelClosed)); + } + #[test] fn test_datacell_try_get() { let cell: DataCell<_> = DataCell::new();