1#![warn(missing_docs)]
46
47use std::error::Error;
48use std::fmt;
49use std::mem;
50use std::os::raw::c_void;
51use std::time::Duration;
52
53use crate::ffi::*;
54
55pub use crate::group::{Group, GroupGuard};
56pub use crate::once::Once;
57pub use crate::queue::{Queue, QueueAttribute, QueuePriority, SuspendGuard};
58pub use crate::sem::{Semaphore, SemaphoreGuard};
59
60pub mod ffi;
62mod group;
63mod queue;
64mod once;
65mod sem;
66
67#[derive(Clone, Debug)]
69pub struct WaitTimeout {
70 duration: Duration,
71}
72
73impl fmt::Display for WaitTimeout {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 write!(f, "Wait timed out after duration {:?}", self.duration)
76 }
77}
78
79impl Error for WaitTimeout { }
80
81fn time_after_delay(delay: Duration) -> dispatch_time_t {
82 delay.as_secs().checked_mul(1_000_000_000).and_then(|i| {
83 i.checked_add(delay.subsec_nanos() as u64)
84 }).and_then(|i| {
85 if i < (i64::max_value() as u64) { Some(i as i64) } else { None }
86 }).map_or(DISPATCH_TIME_FOREVER, |i| unsafe {
87 dispatch_time(DISPATCH_TIME_NOW, i)
88 })
89}
90
91fn context_and_function<F>(closure: F) -> (*mut c_void, dispatch_function_t)
92 where F: FnOnce() {
93 extern fn work_execute_closure<F>(context: Box<F>) where F: FnOnce() {
94 (*context)();
95 }
96
97 let closure = Box::new(closure);
98 let func: extern fn(Box<F>) = work_execute_closure::<F>;
99 unsafe {
100 (mem::transmute(closure), mem::transmute(func))
101 }
102}
103
104fn context_and_sync_function<F>(closure: &mut Option<F>) ->
105 (*mut c_void, dispatch_function_t)
106 where F: FnOnce() {
107 extern fn work_read_closure<F>(context: &mut Option<F>) where F: FnOnce() {
108 let closure = context.take().unwrap();
110 closure();
111 }
112
113 let context: *mut Option<F> = closure;
114 let func: extern fn(&mut Option<F>) = work_read_closure::<F>;
115 unsafe {
116 (context as *mut c_void, mem::transmute(func))
117 }
118}
119
120fn context_and_apply_function<F>(closure: &F) ->
121 (*mut c_void, extern fn(*mut c_void, usize))
122 where F: Fn(usize) {
123 extern fn work_apply_closure<F>(context: &F, iter: usize)
124 where F: Fn(usize) {
125 context(iter);
126 }
127
128 let context: *const F = closure;
129 let func: extern fn(&F, usize) = work_apply_closure::<F>;
130 unsafe {
131 (context as *mut c_void, mem::transmute(func))
132 }
133}