From 76fdcece687af8d82e7b5a6c065988ab80c914cb Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 25 Apr 2015 19:59:32 +0200 Subject: bus_read invokes callback with null message to notify that it is listening on the bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 4 ++-- doc/bus_read.3 | 2 +- src/bus.c | 11 +++++++++++ src/bus.h | 6 ++++++ src/cmdline.c | 14 +++++++++----- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 70b7132..9c92e3a 100644 --- a/Makefile +++ b/Makefile @@ -24,10 +24,10 @@ MAN7 = libbus FLAGS = -std=c99 -Wall -Wextra -pedantic -O2 -LIB_MAJOR = 1 +LIB_MAJOR = 2 LIB_MINOR = 0 LIB_VERSION = ${LIB_MAJOR}.${LIB_MINOR} -VERSION = 1.0.1 +VERSION = 2.0 all: bus doc diff --git a/doc/bus_read.3 b/doc/bus_read.3 index 18bedc0..8f6ce88 100644 --- a/doc/bus_read.3 +++ b/doc/bus_read.3 @@ -6,7 +6,7 @@ bus_read - Listen for new messages a bus int bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data), void *user_data); .SH DESCRIPTION -The \fIbus_read\fP function shall continuously wait for new message to be sent on the bus whose information is stored in \fIbus\fP. Once a message is received, the \fIcallback\fP function shall be invoked. \fImessage\fP should be the recieved message, and \fIuser_data\fP for \fIcallback\fP should be \fIuser_data\fP from \fIbus_read\fP. +The \fIbus_read\fP function shall continuously wait for new message to be sent on the bus whose information is stored in \fIbus\fP. Once a message is received, the \fIcallback\fP function shall be invoked. \fImessage\fP should be the received message, and \fIuser_data\fP for \fIcallback\fP should be \fIuser_data\fP from \fIbus_read\fP. However, once \fIbus_read\fP has ensured that it will receive any message sent on the bus, it shall invoke the \fIcallback\fP function with \fImessage\fP set to \fINULL\fP, to notify the process that it can perform any action that requires that it is listening on the bus. After \fIcallback\fP returns, \fImessage\fP may be override. Therefore \fIcallback\fP should copy \fImessage\fP and start a new thread that uses the copy of \fImessage\fP. \fIcallback\fP shall return -1 on failure, 0 if \fIbus_read\fP should stop listening or 1 if \fIbus_read\fP should continue listening. .SH RETURN VALUES diff --git a/src/bus.c b/src/bus.c index 5875b2b..f4f62c2 100644 --- a/src/bus.c +++ b/src/bus.c @@ -629,6 +629,12 @@ fail: * * 0: stop listening * * 1: continue listening * * -1: an error has occurred + * However, the function [`bus_read`] will invoke + * `callback` with `message` one time directly after + * it has started listening on the bus. This is to + * the the program now it can safely continue with + * any action that requires that the programs is + * listening on the port. * @return 0 on success, -1 on error */ int @@ -636,6 +642,11 @@ bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data) { int r; t(release_semaphore(bus, S, SEM_UNDO)); + t(r = callback(NULL, user_data)); + if (!r) { + t(acquire_semaphore(bus, S, SEM_UNDO)); + return 0; + } for (;;) { t(release_semaphore(bus, Q, 0)); t(zero_semaphore(bus, Q)); diff --git a/src/bus.h b/src/bus.h index 267cac9..abae46b 100644 --- a/src/bus.h +++ b/src/bus.h @@ -162,6 +162,12 @@ int bus_write(const bus_t *bus, const char *message); * * 0: stop listening * * 1: continue listening * * -1: an error has occurred + * However, the function [`bus_read`] will invoke + * `callback` with `message` one time directly after + * it has started listening on the bus. This is to + * the the program now it can safely continue with + * any action that requires that the programs is + * listening on the port. * @return 0 on success, -1 on error */ int bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data), void *user_data); diff --git a/src/cmdline.c b/src/cmdline.c index 40d0136..f9505cc 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -59,8 +59,10 @@ static const char *command; static int spawn_continue(const char *message, void *user_data) { - pid_t pid = fork(); - if (pid) + pid_t pid; + if (!message) + return 1; + if ((pid = fork())) return pid == -1 ? -1 : 1; setenv("arg", message, 1); execlp("sh", "sh", "-c", command, NULL); @@ -75,13 +77,15 @@ spawn_continue(const char *message, void *user_data) * * @param message The received message * @param user_data Not used - * @return 0 (stop listening) on success, -1 on error + * @return 0 (stop listening) on success, -1 on error, or 1 if `message` is `NULL` */ static int spawn_break(const char *message, void *user_data) { - pid_t pid = fork(); - if (pid) + pid_t pid; + if (!message) + return 1; + if (pid = fork()) return pid == -1 ? -1 : 0; setenv("arg", message, 1); execlp("sh", "sh", "-c", command, NULL); -- cgit v1.2.3-70-g09d2