-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsem_xsi.hpp
109 lines (83 loc) · 2.16 KB
/
sem_xsi.hpp
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifndef ZORO_XSI_SEMAPHARE_HPP
#define ZORO_XSI_SEMAPHARE_HPP
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
namespace zoro {
namespace interprocess {
namespace xsi {
inline bool sem_create(::key_t key, int nsem, int &semid)
{
int id, perm;
union semun {
int val;
::semid_ds *buf;
ushort *array;
} semctl_arg;
semid = -1;
perm = 0666;
if (key == IPC_PRIVATE)
return false; //not intended for private semaphores
else if (key == (::key_t) -1)
return false; //probably an ftok() error by caller
if ((id = ::semget(key, nsem+2, (perm & 0x01FF) | IPC_CREAT)) < 0)
return false; //permission problem or tables full
// semaphore set
// [0] : lock, used for creation atomic
// [1] : process-count, process attach it
// [2...]: semaphore used for user
// set all the values to zero
for (int i=0; i<nsem; ++i)
{
semctl_arg.val = 0;
if (::semctl(id, i+2, SETVAL, semctl_arg) < 0)
return false;
}
semid = id;
return true;
}
inline bool sem_open(::key_t key, int nsem, int &semid)
{
int id;
semid = -1;
if (key == IPC_PRIVATE)
return false; //not intended for private semaphores
else if (key == (::key_t) -1)
return false; //probably an ftok() error by caller
if ((id = ::semget(key, nsem+2, 0)) < 0)
return false; //permission problem or tables full
// semaphore set
// [0] : lock, used for creation atomic
// [1] : process-count, process attach it
// [2...]: semaphore used for user
semid = id;
return true;
}
inline bool sem_inc(int id, int ipos)
{
::sembuf op = {
0, +1, SEM_UNDO
};
op.sem_num = ipos+2;
if (::semop(id, &op, 1) < 0)
return false;
return true;
}
inline bool sem_desc(int id, int ipos)
{
::sembuf op = {
0, -1, SEM_UNDO
};
op.sem_num = ipos+2;
if (::semop(id, &op, 1) < 0)
return false;
return true;
}
inline int sem_get(int id, int ipos)
{
return ::semctl(id, ipos+2, GETVAL);
}
} // namespace xsi
} // namespace interprocess
} // namespace zoro
#endi