aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/protocol21
-rw-r--r--src/bus.c11
2 files changed, 28 insertions, 4 deletions
diff --git a/doc/protocol b/doc/protocol
index def8f6f..a846581 100644
--- a/doc/protocol
+++ b/doc/protocol
@@ -14,10 +14,14 @@ broadcast:
with P(X):
Z(W)
Write NUL-terminate message to shared memory
- with V(N):
+ with V(N): -- (1)
Q := 0
Z(S)
+ -- (1) may be omitted if semaphores are known that
+ P(·), Z(·), V(·) cannot create a race condition
+ with a processes running Z(·).
+
listen:
with V(S):
@@ -29,6 +33,17 @@ listen:
break
with V(W):
with P(S):
- Z(S)
- Z(N)
+ Z(S)
+ Z(N)
+
+
+`V(a)` means that semaphore a is released.
+`P(a)` means that semaphore a is acquired.
+`Z(a)` means that the process waits for semaphore a to become 0.
+`with P(a)` that `P(a)` is done before the entering the scope,
+and `V(a)` is done when exiting the scope. It also means that
+these actions [P(a) and V(a)] are undone when the process exits,
+or if the call fails.
+`with V(a)` that `V(a)` is like `with P(a)` that `P(a)` and
+`V(a)` are exchanged.
diff --git a/src/bus.c b/src/bus.c
index 614f7ad..5737fd7 100644
--- a/src/bus.c
+++ b/src/bus.c
@@ -623,22 +623,31 @@ fail:
int
bus_write(const bus_t *bus, const char *message, int flags /* TODO document in man page */)
{
- int state = 0, saved_errno;
+ int saved_errno;
+#ifndef BUS_SEMAPHORES_ARE_SYNCHRONOUS
+ int state = 0;
+#endif
if (acquire_semaphore(bus, X, SEM_UNDO | F(BUS_NOWAIT, IPC_NOWAIT)) == -1)
return -1;
t(zero_semaphore(bus, W, 0));
write_shared_memory(bus, message);
+#ifndef BUS_SEMAPHORES_ARE_SYNCHRONOUS
t(release_semaphore(bus, N, SEM_UNDO)); state++;
+#endif
t(write_semaphore(bus, Q, 0));
t(zero_semaphore(bus, S, 0));
+#ifndef BUS_SEMAPHORES_ARE_SYNCHRONOUS
t(acquire_semaphore(bus, N, SEM_UNDO)); state--;
+#endif
t(release_semaphore(bus, X, SEM_UNDO));
return 0;
fail:
saved_errno = errno;
+#ifndef BUS_SEMAPHORES_ARE_SYNCHRONOUS
if (state > 0)
acquire_semaphore(bus, N, SEM_UNDO);
+#endif
release_semaphore(bus, X, SEM_UNDO);
errno = saved_errno;
return -1;