timebomb/lib.rs
1// Copyright 2015 Colin Sherratt
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15extern crate pulse;
16
17use std::thread;
18use pulse::{Signal, TimeoutError};
19
20/// Run f for at most max_ms, this function will panic if
21/// f is still running.
22pub fn timeout_ms<F>(f: F, max_ms: u32) where F: FnOnce() + Send + 'static {
23 let (signal_start, pulse_start) = Signal::new();
24 let (signal_end, pulse_end) = Signal::new();
25
26 let guard = thread::spawn(|| {
27 pulse_start.pulse();
28 f();
29 pulse_end.pulse();
30 });
31
32 // Wait for the thread to start.
33 // This is done so that a loaded computer
34 // does not timeout before the thread has been started
35 signal_start.wait().unwrap();
36
37 // Wait for the timeout
38 match signal_end.wait_timeout_ms(max_ms) {
39 Err(TimeoutError::Timeout) => {
40 panic!("Timed out");
41 }
42 _ => ()
43 }
44
45 guard.join().unwrap();
46}
47
48#[test]
49fn timeout_ms_no_timeout_ms() {
50 timeout_ms(|| {}, 100);
51}
52
53#[test]
54#[should_panic]
55fn timeout_ms_spin() {
56 timeout_ms(|| loop {}, 100);
57}
58
59#[test]
60#[should_panic]
61fn child_panics() {
62 timeout_ms(|| {
63 panic!("oh no!")
64 }, 100);
65}