suiron/time_out.rs
1//! Functions for limiting execution time.
2//!
3//! This module contains a global variable, SUIRON_STOP_QUERY,
4//! and therefore has 'unsafe' code.
5
6use std::time::Duration;
7use thread_timer::ThreadTimer;
8
9use super::logic_var::*;
10
11static mut SUIRON_STOP_QUERY: bool = false;
12
13/// Create a timer with a timeout in milliseconds.
14///
15/// When the timer times out, it sets the SUIRON_STOP_QUERY
16/// flag to true, effectively halting a query.
17///
18/// # Arguments
19/// * timeout in milliseconds
20/// # Return
21/// * ThreadTimer
22/// # Usage
23/// ```
24/// use suiron::*;
25///
26/// let timer = start_query_timer(300);
27/// ```
28pub fn start_query_timer(milliseconds: u64) -> ThreadTimer {
29 unsafe { SUIRON_STOP_QUERY = false; }
30 let timer = ThreadTimer::new();
31 timer.start(Duration::from_millis(milliseconds),
32 move || { stop_query(); }).unwrap();
33 return timer;
34} // start_query_timer()
35
36/// Cancels query timer. Ignores any issues.
37///
38/// # Argument
39/// * ThreadTimer
40/// # Usage
41/// ```
42/// use suiron::*;
43///
44/// let timer = start_query_timer(30);
45/// cancel_timer(timer);
46/// ```
47pub fn cancel_timer(timer: ThreadTimer) {
48 match timer.cancel() {
49 Ok(_) => {},
50 Err(_) => {},
51 }
52} // cancel_timer()
53
54/// Sets the SUIRON_STOP_QUERY flag to false and LOGIC_VAR_ID to 0.
55///
56/// The SUIRON_STOP_QUERY is checked in count_rules(), in knowledgebase.rs.
57/// Setting it true effectively stops the search for a solution.
58///
59/// In order to keep the substitution set small, the LOGIC_VAR_ID is
60/// reset to 0 at the start of every query.
61pub fn start_query() {
62 unsafe { SUIRON_STOP_QUERY = false; }
63 clear_id();
64}
65
66/// Sets the SUIRON_STOP_QUERY flag to true.
67///
68/// The SUIRON_STOP_QUERY is checked in count_rules(), in knowledgebase.rs.
69/// Setting it `true` effectively stops the search for a solution.
70pub fn stop_query() {
71 unsafe { SUIRON_STOP_QUERY = true; }
72}
73
74/// Returns value of SUIRON_STOP_QUERY.
75///
76/// If the SUIRON_STOP_QUERY is true, it means that the query timed out.
77/// # Return
78/// * true/false
79pub fn query_stopped() -> bool {
80 unsafe { SUIRON_STOP_QUERY }
81}
82
83#[cfg(test)]
84mod test {
85
86 use super::*;
87 use std::thread;
88 use std::time::Duration;
89 use serial_test::serial;
90
91 // Test timer.
92 // The function sleeps for 40 milliseconds, but the
93 // timer times out after 30 milliseconds.
94 #[test]
95 #[serial]
96 fn test_query_timer() {
97 let timer = start_query_timer(30);
98 let flag = query_stopped();
99 assert_eq!(false, flag, "SUIRON_STOP_QUERY should be false.");
100 let delay = Duration::from_millis(40);
101 thread::sleep(delay); // Rust does sleep, Neil Young.
102 cancel_timer(timer);
103 let flag = query_stopped();
104 assert_eq!(true, flag, "SUIRON_STOP_QUERY should be true.");
105 } // test_query_timer()
106
107} // test