2 * Copyright (c) 2000-2001, 2005 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
11 SM_RCSID("@(#)$Id: sem.c,v 1.13 2005/08/12 20:39:59 ca Exp $")
21 ** SM_SEM_START -- initialize semaphores
24 ** key -- key for semaphores.
25 ** nsem -- number of semaphores.
26 ** semflg -- flag for semget(), if 0, use a default.
27 ** owner -- create semaphores.
35 sm_sem_start(key, nsem, semflg, owner)
42 unsigned short *semvals;
46 semflg = (SEM_A|SEM_R)|((SEM_A|SEM_R) >> 3);
48 semflg |= IPC_CREAT|IPC_EXCL;
49 semid = semget(key, nsem, semflg);
57 semvals = (unsigned short *) sm_malloc(nsem * sizeof semvals);
60 semarg.array = semvals;
62 /* initialize semaphore values to be available */
63 for (i = 0; i < nsem; i++)
65 if (semctl(semid, 0, SETALL, semarg) < 0)
76 return (err > 0) ? (0 - err) : -1;
80 ** SM_SEM_STOP -- stop using semaphores.
83 ** semid -- id for semaphores.
94 return semctl(semid, 0, IPC_RMID, NULL);
98 ** SM_SEM_ACQ -- acquire semaphore.
101 ** semid -- id for semaphores.
102 ** semnum -- number of semaphore.
103 ** timeout -- how long to wait for operation to succeed.
111 sm_sem_acq(semid, semnum, timeout)
117 struct sembuf semops[1];
119 semops[0].sem_num = semnum;
120 semops[0].sem_op = -1;
121 semops[0].sem_flg = SEM_UNDO |
122 (timeout != SM_TIME_FOREVER ? 0 : IPC_NOWAIT);
123 if (timeout == SM_TIME_IMMEDIATE || timeout == SM_TIME_FOREVER)
124 return semop(semid, semops, 1);
127 r = semop(semid, semops, 1);
132 } while (timeout > 0);
137 ** SM_SEM_REL -- release semaphore.
140 ** semid -- id for semaphores.
141 ** semnum -- number of semaphore.
142 ** timeout -- how long to wait for operation to succeed.
150 sm_sem_rel(semid, semnum, timeout)
156 struct sembuf semops[1];
159 /* XXX should we check whether the value is already 0 ? */
160 SM_REQUIRE(sm_get_sem(semid, semnum) > 0);
161 #endif /* PARANOID */
163 semops[0].sem_num = semnum;
164 semops[0].sem_op = 1;
165 semops[0].sem_flg = SEM_UNDO |
166 (timeout != SM_TIME_FOREVER ? 0 : IPC_NOWAIT);
167 if (timeout == SM_TIME_IMMEDIATE || timeout == SM_TIME_FOREVER)
168 return semop(semid, semops, 1);
171 r = semop(semid, semops, 1);
176 } while (timeout > 0);
181 ** SM_SEM_GET -- get semaphore value.
184 ** semid -- id for semaphores.
185 ** semnum -- number of semaphore.
188 ** value of semaphore on success.
193 sm_sem_get(semid, semnum)
199 if ((semval = semctl(semid, semnum, GETVAL, NULL)) < 0)
203 #endif /* SM_CONF_SEM */