b311480e |
1 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
973c2be1 |
6 | // This library is free software; you can redistribute it and / or modify it |
7 | // under the terms of the GNU Lesser General Public version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
7fd59977 |
15 | #ifndef WNT |
16 | |
17 | #ifdef HAVE_CONFIG_H |
18 | # include <config.h> |
19 | #endif |
20 | |
21 | #include <Standard_ProgramError.hxx> |
22 | #include <Standard_NullObject.hxx> |
23 | #include <Standard_ConstructionError.hxx> |
24 | #include <OSD_Semaphore.ixx> |
25 | #include <OSD_WhoAmI.hxx> |
26 | |
27 | |
28 | const OSD_WhoAmI Iam = OSD_WSemaphore; |
29 | |
30 | #ifdef HAVE_UNISTD_H |
31 | # include <unistd.h> |
32 | #endif |
33 | |
34 | #include <errno.h> |
35 | #include <stdio.h> |
36 | |
37 | #ifdef HAVE_SYS_TYPES_H |
38 | # include <sys/types.h> |
39 | #endif |
40 | |
41 | #ifdef HAVE_SYS_IPC_H |
42 | # include <sys/ipc.h> |
43 | #endif |
44 | |
45 | #ifdef HAVE_SYS_SEM_H |
46 | # include <sys/sem.h> |
47 | #endif |
48 | |
49 | #ifdef HAVE_SIGNAL_H |
50 | # include <signal.h> |
51 | #endif |
52 | |
53 | #ifdef SEMUN_DEFINED |
54 | /* union semun is defined by including <sys/sem.h> */ |
55 | #else |
56 | /* according to X/OPEN we have to define it ourselves */ |
57 | union semun { |
58 | int val; /* value for SETVAL */ |
59 | struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ |
60 | unsigned short int *array; /* array for GETALL, SETALL */ |
61 | # ifdef SEMUN_BUF_DEFINED /* union semun contains four members not three */ |
62 | struct seminfo *__buf; /* buffer for IPC_INFO */ |
63 | # endif |
64 | }; |
65 | #endif |
66 | |
67 | |
68 | extern "C" int osd_getkey(char *); |
69 | |
70 | // Remark : ifdef DS3 means use of DecStation under ULTRIX |
71 | |
72 | #define CLUSTER_NUMBER 4 |
73 | |
74 | static struct sembuf event_flag ; |
75 | |
76 | OSD_Semaphore::OSD_Semaphore(){ |
77 | mySemId = -1; |
78 | event_flag.sem_num = 0; |
79 | event_flag.sem_op = 0; |
80 | event_flag.sem_flg = 0; |
81 | } |
82 | |
83 | // =============================================================== |
84 | OSD_Semaphore::OSD_Semaphore(const TCollection_AsciiString& Name) |
85 | |
86 | // CREATE a semaphore cluster of 32 events ======================= |
87 | // =============================================================== |
88 | |
89 | |
90 | { |
91 | mySemId = -1; |
92 | event_flag.sem_num = 0; |
93 | event_flag.sem_op = 0; |
94 | event_flag.sem_flg = 0; |
95 | |
96 | if (!Name.IsAscii()) |
97 | Standard_ConstructionError::Raise("OSD_Semaphore::OSD_Semaphore : name"); |
98 | |
99 | myName = Name; |
100 | |
101 | Standard_PCharacter pStr; |
102 | // |
103 | pStr=(Standard_PCharacter)Name.ToCString(); |
104 | myKey = osd_getkey(pStr); |
105 | } |
106 | |
107 | |
108 | |
109 | |
110 | // =============================================================== |
111 | void OSD_Semaphore::Build() |
112 | // Set semaphore into system ===================================== |
113 | // =============================================================== |
114 | { |
115 | mySemId = semget((key_t) myKey,CLUSTER_NUMBER,0750 + IPC_CREAT) ; |
116 | |
117 | if (mySemId == -1) myError.SetValue(errno, Iam, "OSD_Semaphore::Build"); |
118 | } |
119 | |
120 | |
121 | |
122 | // =============================================================== |
123 | void OSD_Semaphore::Open(const TCollection_AsciiString& Name) |
124 | // OPEN a semaphore cluster ================================== |
125 | // =============================================================== |
126 | |
127 | { |
128 | |
129 | if (!Name.IsAscii()) |
130 | Standard_ConstructionError::Raise("OSD_Semaphore::Open"); |
131 | |
132 | myName = Name; |
133 | Standard_PCharacter pStr; |
134 | // |
135 | pStr=(Standard_PCharacter)Name.ToCString(); |
136 | myKey = osd_getkey(pStr); |
137 | |
138 | mySemId = semget((key_t) myKey,0,0) ; |
139 | |
140 | if (mySemId == -1) myError.SetValue(errno, Iam, "OSD_Semaphore::Open"); |
141 | } |
142 | |
143 | |
144 | |
145 | // =============================================================== |
146 | void OSD_Semaphore::Lock() |
147 | // WAIT & LOCK the semaphore attached to the cluster ======== |
148 | // =============================================================== |
149 | |
150 | |
151 | { |
152 | int status ; |
153 | int event=0; |
154 | |
155 | if (myError.Failed()) myError.Perror(); |
156 | |
157 | if (mySemId == -1) |
158 | Standard_ProgramError::Raise("OSD_Semaphore::Lock : semaphore not created"); |
159 | |
160 | event_flag.sem_num = event ; |
161 | event_flag.sem_op = -1 ; |
162 | event_flag.sem_flg = SEM_UNDO; |
163 | |
164 | status = semop((int)mySemId ,&event_flag,1) ; |
165 | |
166 | if (status == -1) myError.SetValue(errno, Iam, "Lock semaphore"); |
167 | } |
168 | |
169 | |
170 | |
171 | // =============================================================== |
172 | void OSD_Semaphore::Free() |
173 | // FREE the semaphore attached to the cluster =============== |
174 | // =============================================================== |
175 | |
176 | { |
177 | int status ; |
178 | |
179 | if (myError.Failed()) myError.Perror(); |
180 | |
181 | if (mySemId == -1) |
182 | Standard_ProgramError::Raise("OSD_Semaphore::Free : semaphore not created"); |
183 | |
184 | event_flag.sem_num = 0 ; |
185 | event_flag.sem_op = 1 ; |
186 | event_flag.sem_flg = IPC_NOWAIT ; |
187 | |
188 | status=semop((int)mySemId ,&event_flag,1) ; |
189 | |
190 | if (status == -1) myError.SetValue(errno, Iam, "OSD_Semaphore::Free"); |
191 | } |
192 | |
193 | |
194 | |
195 | // =============================================================== |
196 | void OSD_Semaphore::Restore() |
197 | // RESET semaphore to initial state ========================= |
198 | // =============================================================== |
199 | |
200 | |
201 | { |
202 | int status; |
203 | int event=0; |
204 | union semun zero_value; |
205 | |
206 | if (myError.Failed()) myError.Perror(); |
207 | |
208 | if (mySemId == -1) |
209 | Standard_ProgramError::Raise("OSD_Semaphore::Restore : semaphore not created"); |
210 | |
211 | zero_value.val = 0; |
212 | |
213 | status = semctl((int)mySemId ,event,SETVAL,zero_value); |
214 | |
215 | if (status == -1) myError.SetValue(errno, Iam, "OSD_Semaphore::Restore semaphore"); |
216 | } |
217 | |
218 | |
219 | |
220 | |
221 | // =============================================================== |
222 | void OSD_Semaphore::SetCounter(const Standard_Integer Value) |
223 | // Set internal Semaphore counter to desired Value ========= |
224 | // =============================================================== |
225 | |
226 | |
227 | { |
228 | int status; |
229 | int event=0; |
230 | union semun param_value; |
231 | |
232 | if (myError.Failed()) myError.Perror(); |
233 | |
234 | if (mySemId == -1) |
235 | Standard_ProgramError::Raise("OSD_Semaphore::SetCounter : semaphore not created"); |
236 | |
237 | param_value.val = (int)Value; |
238 | |
239 | status = semctl((int)mySemId ,event,SETVAL,param_value); |
240 | |
241 | if (status == -1) myError.SetValue(errno, Iam, "OSD_Semaphore::SetCounter semaphore"); |
242 | } |
243 | |
244 | |
245 | |
246 | // =============================================================== |
247 | Standard_Integer OSD_Semaphore::GetCounter() |
248 | // Get value of semaphore counter ============================ |
249 | // =============================================================== |
250 | |
251 | { |
252 | int status; |
253 | int event=0; |
254 | int Value; |
255 | union semun param_value; |
256 | |
257 | if (myError.Failed()) myError.Perror(); |
258 | |
259 | if (mySemId == -1) |
260 | Standard_ProgramError::Raise("OSD_Semaphore::GetCounter : semaphore not created"); |
261 | |
262 | param_value.array = (ushort *)&Value; |
263 | status = semctl((int)mySemId ,event,GETVAL,param_value); |
264 | |
265 | if (status == -1) |
266 | myError.SetValue(errno, Iam, "OSD_Semaphore::GetCounter semaphore"); |
267 | return (Value); |
268 | } |
269 | |
270 | |
271 | |
272 | // =============================================================== |
273 | void OSD_Semaphore::Delete() |
274 | // CLOSE semaphore attached to cluster ================== |
275 | // =============================================================== |
276 | |
277 | { |
278 | int status; |
279 | union semun param_value; |
280 | |
281 | if (myError.Failed()) myError.Perror(); |
282 | |
283 | if (mySemId == -1) |
284 | Standard_ProgramError::Raise("OSD_Semaphore::Delete : semaphore not created"); |
285 | |
286 | param_value.array = NULL; |
287 | status = semctl((int)mySemId ,IPC_RMID, 0, param_value); |
288 | |
289 | if (status == -1) |
290 | myError.SetValue(errno, Iam, "OSD_Semaphore::Delete semaphore"); |
291 | mySemId = -1; |
292 | } |
293 | |
294 | |
295 | |
296 | // =============================================================== |
297 | void OSD_Semaphore::Reset(){ |
298 | // =============================================================== |
299 | myError.Reset(); |
300 | } |
301 | |
302 | // =============================================================== |
303 | Standard_Boolean OSD_Semaphore::Failed()const{ |
304 | // =============================================================== |
305 | return( myError.Failed()); |
306 | } |
307 | |
308 | // =============================================================== |
309 | void OSD_Semaphore::Perror() { |
310 | // =============================================================== |
311 | myError.Perror(); |
312 | } |
313 | |
314 | |
315 | // =============================================================== |
316 | Standard_Integer OSD_Semaphore::Error()const{ |
317 | // =============================================================== |
318 | return( myError.Error()); |
319 | } |
320 | #endif |