1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
pub struct Latch {
inner: *mut ffi::Latch,
}
impl Latch {
pub fn new() -> Self {
Latch {
inner: unsafe { ffi::box_latch_new() },
}
}
pub fn lock(&self) -> LatchGuard {
unsafe { ffi::box_latch_lock(self.inner) };
LatchGuard { latch: self }
}
pub fn try_lock(&self) -> Option<LatchGuard> {
if unsafe { ffi::box_latch_trylock(self.inner) } == 0 {
Some(LatchGuard { latch: self })
} else {
None
}
}
}
impl Drop for Latch {
fn drop(&mut self) {
unsafe { ffi::box_latch_delete(self.inner) }
}
}
pub struct LatchGuard<'a> {
latch: &'a Latch,
}
impl<'a> Drop for LatchGuard<'a> {
fn drop(&mut self) {
unsafe { ffi::box_latch_unlock(self.latch.inner) }
}
}
pub mod ffi {
use std::os::raw::c_int;
#[repr(C)]
pub struct Latch {
_unused: [u8; 0],
}
extern "C" {
pub fn box_latch_new() -> *mut Latch;
pub fn box_latch_delete(latch: *mut Latch);
pub fn box_latch_lock(latch: *mut Latch);
pub fn box_latch_trylock(latch: *mut Latch) -> c_int;
pub fn box_latch_unlock(latch: *mut Latch);
}
}