/* Implement a binary semaphore protocol using System V semaphores. */ #include #include #include "common.h" #include "binary_sems.h" Boolean bsUseSemUndo = FALSE; Boolean bsRetryOnEintr = TRUE; int /* Initialize semaphore to 1 (i.e., "available") */ initSemAvailable(int semId, int semNum) { union semun arg; arg.val = 1; return semctl(semId, semNum, SETVAL, arg); } int /* Initialize semaphore to 0 (i.e., "in use") */ initSemInUse(int semId, int semNum) { union semun arg; arg.val = 0; return semctl(semId, semNum, SETVAL, arg); } /* Reserve semaphore (blocking), return 0 on success, or -1 with 'errno' set to EINTR if operation was interrupted by a signal handler */ int /* Reserve semaphore - decrement it by 1 */ reserveSem(int semId, int semNum) { struct sembuf sops; sops.sem_num = semNum; sops.sem_op = -1; sops.sem_flg = bsUseSemUndo ? SEM_UNDO : 0; while (semop(semId, &sops, 1) == -1) if (errno != EINTR || !bsRetryOnEintr) return -1; return 0; } int /* Release semaphore - increment it by 1 */ releaseSem(int semId, int semNum) { struct sembuf sops; sops.sem_num = semNum; sops.sem_op = 1; sops.sem_flg = bsUseSemUndo ? SEM_UNDO : 0; return semop(semId, &sops, 1); }