classic_sync/
semaphore.rs1use std::time::Duration;
2
3use crate::binding::{self, SemPtr, c_destroy_semaphore,c_p_semaphore_timed, c_init_semaphore, c_p_semaphore, c_v_semaphore, SEM_E_TIMEOUT, SEM_P_V_ON_UNINIT, SEM_INIT_DOUBLE_INIT};
4
5#[derive(Debug)]
6pub struct SemaphoreError {
7 code:i32
8}
9
10impl SemaphoreError {
33 pub fn code(&self) -> i32 {
34 return self.code;
35 }
36
37 pub fn is_timeout(&self) -> bool {
38 return self.code == SEM_E_TIMEOUT;
39 }
40
41 pub fn msg(&self)->String {
42 if self.code == SEM_P_V_ON_UNINIT {
43 "Use of uninitialized SEMAPHORE".into()
44 } else if self.code == SEM_INIT_DOUBLE_INIT {
45 "Can't double init SEMAPHORE".into()
46 } else if self.code == SEM_E_TIMEOUT {
47 "Semaphore wait timed out".into()
48 } else {
49 format!("SyscallError code: {}", self.code)
50 }
51 }
52}
53impl std::fmt::Display for SemaphoreError {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 write!(f, "SemaphoreError code :{}, message:{}", self.code, self.msg())
56 }
57}
58
59impl std::error::Error for SemaphoreError {
60}
61
62type SemaphoreResult<T> = Result<T, SemaphoreError>;
63
64impl SemPtr {
65 fn init(&self, count: i32)-> i32 {
66 unsafe {
67 return c_init_semaphore(self, count);
68 }
69 }
70 fn close(&self) -> i32 {
71 unsafe {
72 return c_destroy_semaphore(self);
73 }
74 }
75
76 fn p(&self) -> i32 {
77 unsafe {
78 return c_p_semaphore(self);
79 }
80 }
81
82 fn p_timeout(&self, nanos:i64) -> i32 {
83 unsafe {
84 return c_p_semaphore_timed(self, nanos);
85 }
86 }
87 fn v(&self) -> i32 {
88 unsafe {
89 return c_v_semaphore(self);
90 }
91 }
92}
93
94#[derive(Debug)]
95pub struct Semaphore {
96 ptr: SemPtr,
97}
98
99fn test<T>(what:T) where
100T: Send {
101
102}
103impl Semaphore {
104 pub fn new(count:i32) -> Semaphore {
105 let ptr = SemPtr {
106 sem_ptr: 0,
107 };
108 let result = ptr.init(count);
109 if result != 0 {
110 panic!("Semaphore init error {result}");
111 }
112 return Semaphore {
113 ptr
114 };
115 }
116
117 pub fn v(&self) {
118 let result = self.ptr.v();
119 if result == 0 {
120 return;
121 }
122 panic!("v() operation on semaphore can't fail");
123 }
124
125 pub fn p_timeout(&self, duration:Duration) -> bool {
126 let nanos = duration.as_nanos();
127 let result = self.ptr.p_timeout(nanos as i64);
128 if result == 0 {
129 return true;
130 }
131 return false;
132 }
133
134 pub fn p(&self) {
135 let result = self.ptr.p();
136
137 if result != 0 {
138 panic!("p() operation didn't work");
139 }
140 }
141}
142
143impl Drop for Semaphore {
144 fn drop(&mut self) {
145 self.ptr.close();
146 }
147}