Authors: Paul Quinn <paulq@corel.ca>, Zygo Blaxell <zygob@corel.ca>
[wine/multimedia.git] / ipc / shm_semaph.c
blobd63f1e57acee336719c2772677c0aa3245255c5d
1 /***************************************************************************
2 * Copyright 1995, Technion, Israel Institute of Technology
3 * Electrical Eng, Software Lab.
4 * Author: Michael Veksler.
5 ***************************************************************************
6 * File: shm_semaph.c
7 * Purpose: Handle semaphores for shared memory operations.
8 ***************************************************************************
9 */
10 #ifdef CONFIG_IPC
12 #define inline __inline__
13 #include <assert.h>
14 #include <unistd.h>
15 #include <sys/sem.h>
16 #include <errno.h>
17 #include "debug.h"
18 #include "shm_semaph.h"
19 #define SEM_READ 0
20 #define SEM_WRITE 1
22 /* IMPORTANT: Make sure that killed process will not lock everything.
23 * If possible, restrict usage of these functions.
25 void shm_read_wait(shm_sem semid)
27 struct sembuf sop[2];
28 int ret;
30 TRACE(sem,"(%d)\n",semid);
31 sop[0].sem_num=SEM_READ;
32 sop[0].sem_op=1; /* add this read instance */
33 sop[0].sem_flg=SEM_UNDO; /* undo in case process dies */
35 sop[1].sem_num=SEM_WRITE;
36 sop[1].sem_op=0; /* wait until no writing instance exists */
37 sop[1].sem_flg=SEM_UNDO;
39 do {
40 ret=semop (semid,sop , 2);
41 } while (ret<0 && errno==EINTR); /* interrupted system call? */
43 if (ret<0)
44 WARN(sem,"(semid=%d,errno=%d): Failed semaphore lock for read\n",
45 semid, errno);
47 void shm_write_wait(shm_sem semid)
49 struct sembuf sop[3];
50 int ret;
52 TRACE(sem,"(%d)\n",semid);
53 sop[0].sem_num=SEM_READ;
54 sop[0].sem_op=0; /* wait until no reading instance exist */
55 sop[0].sem_flg=SEM_UNDO;
57 sop[1].sem_num=SEM_WRITE;
58 sop[1].sem_op=1; /* writing is in progress - disable read */
59 sop[1].sem_flg=SEM_UNDO; /* undo if process dies */
61 sop[2].sem_num=SEM_READ;
62 sop[2].sem_op=1; /* disable new writes */
63 sop[2].sem_flg=SEM_UNDO;
65 do {
66 ret=semop (semid,sop , 3);
67 } while (ret<0 && errno==EINTR); /* interrupted system call? */
69 if (ret<0) /* test for the error */
70 WARN(sem,"(semid=%d,errno=%d): Failed semaphore lock for write\n",
71 semid, errno);
73 void shm_write_signal(shm_sem semid)
75 struct sembuf sop[2];
76 int ret;
78 TRACE(sem,"(%d)\n",semid);
79 sop[0].sem_num=SEM_READ;
80 sop[0].sem_op=-1;
81 sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
83 sop[1].sem_num=SEM_WRITE;
84 sop[1].sem_op=-1;
85 sop[1].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
87 do {
88 ret=semop (semid,sop , 2);
89 } while (ret<0 && errno==EINTR); /* interrupted system call? */
91 if (ret<0) /* test for the error */
92 WARN(sem,"(semid=%d,errno=%d): Failed semaphore unlock for write\n",
93 semid, errno);
96 void shm_read_signal(shm_sem semid)
98 struct sembuf sop[2];
99 int ret;
101 TRACE(sem,"(%d)\n",semid);
102 sop[0].sem_num=SEM_READ;
103 sop[0].sem_op=-1;
104 sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
106 do {
107 ret=semop (semid,sop , 1);
108 } while (ret<0 && errno==EINTR); /* interrupted system call? */
110 if (ret<0) /* test for the error */
111 WARN(sem,"(semid=%d,errno=%d): Failed semaphore unlock for read\n",
112 semid, errno);
115 void shm_sem_init(shm_sem *sptr)
117 shm_sem semid;
118 union semun arg;
120 semid=semget (IPC_PRIVATE, 2, 0700 | IPC_CREAT);
122 arg.val=0;
123 semctl (semid, 0, SETVAL, arg);
124 semctl (semid, 1, SETVAL, arg);
125 *sptr=semid;
128 void shm_sem_done(shm_sem *semptr)
130 union semun arg;
132 semctl (*semptr, 0, IPC_RMID , arg);
133 semctl (*semptr, 1, IPC_RMID , arg);
135 *semptr= -1;
138 #endif /* CONFIG_IPC */