1use std::{ffi::CString, io};
9
10use bitflags::bitflags;
11
12bitflags! {
13 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14 pub struct OpenOptions: libc::c_int {
15 const CREATE = libc::O_CREAT;
17 const READ = libc::O_RDONLY;
19 const WRITE = libc::O_WRONLY;
21 }
22
23 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24 pub struct OpenMode: libc::mode_t {
25 const R_USR = libc::S_IRUSR;
27 const W_USR = libc::S_IWUSR;
29 const R_GRP = libc::S_IRGRP;
31 const W_GRP = libc::S_IWGRP;
33 const R_OTH = libc::S_IROTH;
35 const W_OTH = libc::S_IWOTH;
37 }
38}
39
40#[derive(Debug)]
41pub struct Sem {
42 ptr: *mut libc::sem_t,
43}
44
45impl Sem {
46 pub fn open(
48 name: &str,
49 oflags: OpenOptions,
50 mode: OpenMode,
51 initial: usize,
52 ) -> io::Result<Self> {
53 let cstr = CString::new(name).unwrap();
54 let r = unsafe {
55 libc::sem_open(
56 cstr.as_ptr(),
57 oflags.bits(),
58 mode.bits() as libc::c_uint,
59 initial,
60 )
61 };
62 if r == libc::SEM_FAILED {
63 return Err(io::Error::last_os_error());
64 }
65
66 Ok(Self {
67 ptr: r as *mut libc::sem_t,
68 })
69 }
70
71 pub fn post(&self) -> io::Result<()> {
73 let r = unsafe { libc::sem_post(self.ptr) };
74 if r != 0 {
75 return Err(io::Error::last_os_error());
76 }
77
78 Ok(())
79 }
80
81 pub fn wait(&self) -> io::Result<()> {
83 let r = unsafe { libc::sem_wait(self.ptr) };
84 if r != 0 {
85 return Err(io::Error::last_os_error());
86 }
87
88 Ok(())
89 }
90}
91
92impl Drop for Sem {
93 fn drop(&mut self) {
94 unsafe { libc::sem_close(self.ptr) };
95 }
96}
97
98unsafe impl Send for Sem {}
99unsafe impl Sync for Sem {}