1use core::{convert::TryInto, time::Duration};
2
3use crate::{
4 bindings,
5 error::{from_errno, Error, SentinelError},
6};
7
8pub struct Semaphore(bindings::sem_t);
10
11impl Semaphore {
12 #[inline]
13 pub fn new(max_count: u32, init_count: u32) -> Self {
15 Self::try_new(max_count, init_count)
16 .unwrap_or_else(|err| panic!("failed to create semaphore: {}", err))
17 }
18
19 pub fn try_new(max_count: u32, init_count: u32) -> Result<Self, Error> {
21 Ok(Self(
22 unsafe { bindings::sem_create(max_count, init_count) }.check()?,
23 ))
24 }
25
26 #[inline]
27 pub fn wait(&self, timeout: Duration) -> Result<(), Error> {
31 if unsafe { bindings::sem_wait(self.0, timeout.as_millis().try_into()?) } {
32 Ok(())
33 } else {
34 Err(from_errno())
35 }
36 }
37
38 #[inline]
39 pub fn post(&self) -> Result<(), Error> {
42 if unsafe { bindings::sem_post(self.0) } {
43 Ok(())
44 } else {
45 Err(from_errno())
46 }
47 }
48
49 #[inline]
50 pub fn count(&self) -> u32 {
52 unsafe { bindings::sem_get_count(self.0) }
53 }
54}
55
56impl Drop for Semaphore {
57 fn drop(&mut self) {
58 unsafe { bindings::sem_delete(self.0) }
59 }
60}
61
62unsafe impl Send for Semaphore {}
63
64unsafe impl Sync for Semaphore {}