Skip to content

Commit 78ee7cf

Browse files
authored
add a way to join_timeout without consuming the handle (#47)
1 parent 7cde03b commit 78ee7cf

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

examples/timeout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::Duration;
55
fn main() {
66
procspawn::init();
77

8-
let handle = spawn((), |()| {
8+
let mut handle = spawn((), |()| {
99
thread::sleep(Duration::from_secs(10));
1010
});
1111

src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ enum SpawnErrorKind {
126126
IpcChannelClosed(io::Error),
127127
Cancelled,
128128
TimedOut,
129+
Consumed,
129130
}
130131

131132
impl SpawnError {
@@ -178,6 +179,10 @@ impl SpawnError {
178179
kind: SpawnErrorKind::TimedOut,
179180
}
180181
}
182+
183+
pub(crate) fn new_consumed() -> SpawnError {
184+
SpawnError { kind: SpawnErrorKind::Consumed }
185+
}
181186
}
182187

183188
impl std::error::Error for SpawnError {
@@ -188,6 +193,7 @@ impl std::error::Error for SpawnError {
188193
SpawnErrorKind::Panic(_) => None,
189194
SpawnErrorKind::Cancelled => None,
190195
SpawnErrorKind::TimedOut => None,
196+
SpawnErrorKind::Consumed => None,
191197
SpawnErrorKind::IpcChannelClosed(ref err) => Some(err),
192198
}
193199
}
@@ -201,6 +207,7 @@ impl fmt::Display for SpawnError {
201207
SpawnErrorKind::Panic(ref p) => write!(f, "process spawn error: panic: {}", p),
202208
SpawnErrorKind::Cancelled => write!(f, "process spawn error: call cancelled"),
203209
SpawnErrorKind::TimedOut => write!(f, "process spawn error: timed out"),
210+
SpawnErrorKind::Consumed => write!(f, "process spawn error: result already consumed"),
204211
SpawnErrorKind::IpcChannelClosed(_) => write!(
205212
f,
206213
"process spawn error: remote side closed (might have panicked on serialization)"

src/proc.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,29 @@ impl<T: Serialize + DeserializeOwned> JoinHandle<T> {
524524
}
525525

526526
/// Like `join` but with a timeout.
527-
pub fn join_timeout(self, timeout: Duration) -> Result<T, SpawnError> {
527+
///
528+
/// Can be called multiple times. If anything other than a timeout error is returned, the
529+
/// handle becomes unusuable, and subsequent calls to either `join` or `join_timeout` will
530+
/// return an error.
531+
pub fn join_timeout(&mut self, timeout: Duration) -> Result<T, SpawnError> {
528532
match self.inner {
529-
Ok(JoinHandleInner::Process(mut handle)) => handle.join_timeout(timeout),
530-
Ok(JoinHandleInner::Pooled(mut handle)) => handle.join_timeout(timeout),
531-
Err(err) => Err(err),
533+
Ok(ref mut handle_inner) => {
534+
let result = match handle_inner {
535+
JoinHandleInner::Process(ref mut handle) => handle.join_timeout(timeout),
536+
JoinHandleInner::Pooled(ref mut handle) => handle.join_timeout(timeout),
537+
};
538+
539+
if result.is_ok() {
540+
self.inner = Err(SpawnError::new_consumed());
541+
}
542+
543+
result
544+
}
545+
Err(ref mut err) => {
546+
let mut rv_err = SpawnError::new_consumed();
547+
mem::swap(&mut rv_err, err);
548+
Err(rv_err)
549+
}
532550
}
533551
}
534552
}

tests/test_basic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ fn test_nested() {
7373

7474
#[test]
7575
fn test_timeout() {
76-
let handle = spawn((), |()| {
76+
let mut handle = spawn((), |()| {
7777
thread::sleep(Duration::from_secs(10));
7878
});
7979

8080
let err = handle.join_timeout(Duration::from_millis(100)).unwrap_err();
8181
assert!(err.is_timeout());
8282

83-
let handle = spawn((), |()| {
83+
let mut handle = spawn((), |()| {
8484
thread::sleep(Duration::from_millis(100));
8585
42
8686
});

tests/test_pool.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn test_basic() {
2121

2222
let mut ok = 0;
2323
let mut failed = 0;
24-
for handle in handles {
24+
for mut handle in handles {
2525
if handle.join_timeout(Duration::from_secs(5)).is_ok() {
2626
ok += 1;
2727
} else {
@@ -62,14 +62,14 @@ fn test_overload() {
6262
fn test_timeout() {
6363
let pool = Pool::new(2).unwrap();
6464

65-
let handle = pool.spawn((), |()| {
65+
let mut handle = pool.spawn((), |()| {
6666
thread::sleep(Duration::from_secs(10));
6767
});
6868

6969
let err = handle.join_timeout(Duration::from_millis(100)).unwrap_err();
7070
assert!(err.is_timeout());
7171

72-
let handle = pool.spawn((), |()| {
72+
let mut handle = pool.spawn((), |()| {
7373
thread::sleep(Duration::from_millis(100));
7474
42
7575
});

0 commit comments

Comments
 (0)