current version
[opsoft_test.git] / gclib2 / modules / IPC / ipc.cxx
blob854b09d693340c6038db42e857037b1648c82230
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
4 *
5 */
7 #include <sys/types.h>
8 #include <sys/ipc.h>
9 #include <sys/sem.h>
10 #include <sys/msg.h>
12 /// \file ipc.c Межпроцессорные функции.
14 /*! \page IPCModule Межпроцессорное взаимодействие.
15 * \see ipc.c
18 inline void __semset (struct sembuf * action, int num, int op)
20 action->sem_flg = SEM_UNDO;
21 action->sem_num = num;
22 action->sem_op = op;
25 enum {
26 hold_read = 0,
27 hold_write = 1,
30 inline void __sem_zero (int sem, int num) // = 0
32 semctl (sem, num, SETVAL, 0);
35 int __sem_try_key (int *KEY, int count) // = 1
37 int key = 9900;
38 int id;
40 while (key < 10000) {
41 id = semget (key, count, (0600|IPC_CREAT));
42 if (id < 0) {
43 key++;
44 continue;
47 if (KEY)
48 *KEY = key;
50 return id;
53 return -1;
56 int __sem_init_one (int key, int count) // = 1
58 int id;
59 id = semget (key, 1, (0600|IPC_CREAT));
60 if (id > 0)
61 __sem_zero (id, 0);
62 return id;
65 /*! \brief Инициализировать семафор.
66 * \param KEY - указатель на номер ключа. Если не задан - выбирается рандомный и записывается в *KEY.
67 * \return Код (id) семафора, который используется во всех остальных функциях.
69 int sem_init (int * KEY)
71 int key = 9900;
72 int id;
74 if (KEY && *KEY)
75 id = __sem_init_one (*KEY, 1);
76 else
77 id = __sem_try_key (&key, 1);
79 if (id < 0)
80 return id;
82 __sem_zero (id, 0);
83 if (KEY)
84 *KEY = key;
86 return id;
89 /// Получить идентификатор существующего семафора.
90 int sem_get (int key)
92 return semget (key, 1, 0600);
95 /*! \brief Заблокировать семафор.
96 * \param sem - код (id) семафора.
98 int down (int sem)
100 struct sembuf actions[2];
101 __semset (&actions[0], 0, 0);
102 __semset (&actions[1], 0, +1);
103 return semop (sem, actions, 2);
106 /*! \brief Разблокировать семафор.
107 * \param sem - код (id) семафора.
109 int up (int sem)
111 struct sembuf actions[1];
112 __semset (&actions[0], 0, -1);
113 return semop (sem, actions, 1);
116 /*! \brief Инициализировать семафор (чтение/запись).
117 * \param KEY - указатель на номер ключа. Если не задан - выбирается рандомный и записывается в *KEY.
118 * \return Код (id) семафора, который используется во всех остальных функциях.
120 int sem_init_rw (int * KEY)
122 int id;
124 if (KEY && *KEY)
125 id = __sem_init_one (*KEY, 2);
126 else
127 id = __sem_try_key (KEY, 2);
129 if (id < 0)
130 return id;
132 __sem_zero (id, hold_read);
133 __sem_zero (id, hold_write);
135 return id;
138 /*! \brief Заблокировать семафор (чтение).
139 * \param sem - код (id) семафора.
141 int down_read (int sem)
143 struct sembuf actions[2];
144 __semset (&actions[0], hold_write, 0);
145 __semset (&actions[1], hold_read, +1);
146 return semop (sem, actions, 2);
149 /*! \brief Разблокировать семафор (чтение).
150 * \param sem - код (id) семафора.
152 int up_read (int sem)
154 struct sembuf actions[1];
155 __semset (&actions[0], hold_read, -1);
156 return semop (sem, actions, 1);
159 /*! \brief Заблокировать семафор (запись).
160 * \param sem - код (id) семафора.
162 int down_write (int sem)
164 struct sembuf actions[3];
165 __semset (&actions[0], hold_read, 0);
166 __semset (&actions[1], hold_write, 0);
167 __semset (&actions[2], hold_write, +1);
168 return semop (sem, actions, 3);
171 /*! \brief Разлокировать семафор (запись).
172 * \param sem - код (id) семафора.
174 int up_write (int sem)
176 struct sembuf actions[2];
177 __semset (&actions[0], hold_write, -1);
178 return semop (sem, actions, 1);
181 int __msg_try_key (int *KEY)
183 int key = 9900;
184 int id;
186 if (KEY && *KEY != 0) {
187 id = msgget (key, (0600|IPC_CREAT|IPC_EXCL));
188 return id;
191 while (key < 10000) {
192 id = msgget (key, (0600|IPC_CREAT|IPC_EXCL));
193 if (id < 0) {
194 ++key;
195 continue;
198 if (KEY)
199 *KEY = key;
201 return id;
204 return -1;
207 /*! \brief Инициализировать пул сообщений.
208 * \param KEY - указатель на номер ключа. Если не задан - выбирается рандомный и записывается в *KEY.
209 * \return Код (id) пула сообщений, который используется во всех остальных функциях.
211 int msg_init (int *KEY)
213 return __msg_try_key (KEY);