diff --git a/src/pool.rs b/src/pool.rs index 8158535..ed165a2 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -62,10 +62,7 @@ impl PooledHandle { match self.waiter_rx.recv_timeout(timeout) { Ok(Ok(rv)) => Ok(rv), Ok(Err(err)) => Err(err), - Err(mpsc::RecvTimeoutError::Timeout) => { - self.kill().ok(); - Err(SpawnError::new_timeout()) - } + Err(mpsc::RecvTimeoutError::Timeout) => Err(SpawnError::new_timeout()), Err(mpsc::RecvTimeoutError::Disconnected) => Err(SpawnError::new_remote_close()), } } diff --git a/src/proc.rs b/src/proc.rs index 2ba2846..06fba31 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -515,11 +515,15 @@ impl JoinHandle { /// Wait for the child process to return a result. /// /// If the join handle was created from a pool the join is virtualized. - pub fn join(self) -> Result { - match self.inner { - Ok(JoinHandleInner::Process(mut handle)) => handle.join(), - Ok(JoinHandleInner::Pooled(mut handle)) => handle.join(), - Err(err) => Err(err), + pub fn join(mut self) -> Result { + match &mut self.inner { + Ok(JoinHandleInner::Process(ref mut handle)) => handle.join(), + Ok(JoinHandleInner::Pooled(ref mut handle)) => handle.join(), + Err(err) => { + let mut rv_err = SpawnError::new_consumed(); + mem::swap(&mut rv_err, err); + Err(rv_err) + } } } @@ -551,6 +555,12 @@ impl JoinHandle { } } +impl Drop for JoinHandle { + fn drop(&mut self) { + self.kill().ok(); + } +} + /// Spawn a new process to run a function with some payload. /// /// ```rust,no_run diff --git a/tests/test_pool.rs b/tests/test_pool.rs index c87e2d5..3745f6a 100644 --- a/tests/test_pool.rs +++ b/tests/test_pool.rs @@ -77,3 +77,22 @@ fn test_timeout() { let val = handle.join_timeout(Duration::from_secs(2)).unwrap(); assert_eq!(val, 42); } + +#[test] +fn test_timeout_twice() { + let pool = Pool::new(2).unwrap(); + + let mut handle = pool.spawn((), |()| { + thread::sleep(Duration::from_secs(5)); + 42 + }); + + let err = handle.join_timeout(Duration::from_millis(100)).unwrap_err(); + assert!(err.is_timeout()); + + let err = handle.join_timeout(Duration::from_millis(100)).unwrap_err(); + assert!(err.is_timeout()); + + let val = handle.join_timeout(Duration::from_secs(6)).unwrap(); + assert_eq!(val, 42); +}