]> git.lizzy.rs Git - rust.git/blob - tests/run-pass/concurrency/libc_pthread_cond.rs
Review comments
[rust.git] / tests / run-pass / concurrency / libc_pthread_cond.rs
1 // ignore-windows: No libc on Windows
2 // ignore-macos: pthread_condattr_setclock is not supported on MacOS.
3 // compile-flags: -Zmiri-disable-isolation
4
5 #![feature(rustc_private)]
6
7 /// Test that conditional variable timeouts are working properly with both
8 /// monotonic and system clocks.
9 extern crate libc;
10
11 use std::mem;
12 use std::time::Instant;
13
14 fn test_timed_wait_timeout(clock_id: i32) {
15     unsafe {
16         let mut attr: libc::pthread_condattr_t = mem::zeroed();
17         assert_eq!(libc::pthread_condattr_init(&mut attr as *mut _), 0);
18         assert_eq!(libc::pthread_condattr_setclock(&mut attr as *mut _, clock_id), 0);
19
20         let mut cond: libc::pthread_cond_t = mem::zeroed();
21         assert_eq!(libc::pthread_cond_init(&mut cond as *mut _, &attr as *const _), 0);
22         assert_eq!(libc::pthread_condattr_destroy(&mut attr as *mut _), 0);
23
24         let mut mutex: libc::pthread_mutex_t = mem::zeroed();
25
26         let mut now: libc::timespec = mem::zeroed();
27         assert_eq!(libc::clock_gettime(clock_id, &mut now), 0);
28         // Waiting for a second... mostly because waiting less requires mich more tricky arithmetic.
29         // FIXME: wait less.
30         let timeout = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: now.tv_nsec };
31
32         assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
33         let current_time = Instant::now();
34         assert_eq!(
35             libc::pthread_cond_timedwait(&mut cond as *mut _, &mut mutex as *mut _, &timeout),
36             libc::ETIMEDOUT
37         );
38         let elapsed_time = current_time.elapsed().as_millis();
39         assert!(900 <= elapsed_time && elapsed_time <= 1300);
40
41         // Test that invalid nanosecond values (above 10^9 or negative) are rejected with the
42         // correct error code.
43         let invalid_timeout_1 = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: 1_000_000_000 };
44         assert_eq!(
45             libc::pthread_cond_timedwait(
46                 &mut cond as *mut _,
47                 &mut mutex as *mut _,
48                 &invalid_timeout_1
49             ),
50             libc::EINVAL
51         );
52         let invalid_timeout_2 = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: -1 };
53         assert_eq!(
54             libc::pthread_cond_timedwait(
55                 &mut cond as *mut _,
56                 &mut mutex as *mut _,
57                 &invalid_timeout_2
58             ),
59             libc::EINVAL
60         );
61         // Test that invalid second values (negative) are rejected with the correct error code.
62         let invalid_timeout_3 = libc::timespec { tv_sec: -1, tv_nsec: 0 };
63         assert_eq!(
64             libc::pthread_cond_timedwait(
65                 &mut cond as *mut _,
66                 &mut mutex as *mut _,
67                 &invalid_timeout_3
68             ),
69             libc::EINVAL
70         );
71
72         assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
73         assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
74         assert_eq!(libc::pthread_cond_destroy(&mut cond as *mut _), 0);
75     }
76 }
77
78 fn main() {
79     test_timed_wait_timeout(libc::CLOCK_MONOTONIC);
80     test_timed_wait_timeout(libc::CLOCK_REALTIME);
81 }