2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
12 /// \file ipc.c Межпроцессорные функции.
14 /*! \page IPCModule Межпроцессорное взаимодействие.
18 inline void __semset (struct sembuf
* action
, int num
, int op
)
20 action
->sem_flg
= SEM_UNDO
;
21 action
->sem_num
= num
;
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
41 id
= semget (key
, count
, (0600|IPC_CREAT
));
56 int __sem_init_one (int key
, int count
) // = 1
59 id
= semget (key
, 1, (0600|IPC_CREAT
));
65 /*! \brief Инициализировать семафор.
66 * \param KEY - указатель на номер ключа. Если не задан - выбирается рандомный и записывается в *KEY.
67 * \return Код (id) семафора, который используется во всех остальных функциях.
69 int sem_init (int * KEY
)
75 id
= __sem_init_one (*KEY
, 1);
77 id
= __sem_try_key (&key
, 1);
89 /// Получить идентификатор существующего семафора.
92 return semget (key
, 1, 0600);
95 /*! \brief Заблокировать семафор.
96 * \param sem - код (id) семафора.
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) семафора.
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
)
125 id
= __sem_init_one (*KEY
, 2);
127 id
= __sem_try_key (KEY
, 2);
132 __sem_zero (id
, hold_read
);
133 __sem_zero (id
, hold_write
);
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
)
186 if (KEY
&& *KEY
!= 0) {
187 id
= msgget (key
, (0600|IPC_CREAT
|IPC_EXCL
));
191 while (key
< 10000) {
192 id
= msgget (key
, (0600|IPC_CREAT
|IPC_EXCL
));
207 /*! \brief Инициализировать пул сообщений.
208 * \param KEY - указатель на номер ключа. Если не задан - выбирается рандомный и записывается в *KEY.
209 * \return Код (id) пула сообщений, который используется во всех остальных функциях.
211 int msg_init (int *KEY
)
213 return __msg_try_key (KEY
);