aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-05-17 14:28:20 +0200
committerMattias Andrée <maandree@operamail.com>2015-05-17 14:28:20 +0200
commit0f31d194025df5d63fcee65e32baa90cc5aa0ad6 (patch)
tree83ff9e158ba9df44dc8bb1a3c4ff6304ceb86a29
parentimplemented timed write, read and poll (diff)
downloadbus-0f31d194025df5d63fcee65e32baa90cc5aa0ad6.tar.gz
bus-0f31d194025df5d63fcee65e32baa90cc5aa0ad6.tar.bz2
bus-0f31d194025df5d63fcee65e32baa90cc5aa0ad6.tar.xz
add timed example and fix timed polling
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--doc/examples/nonblocking/poll.c4
-rw-r--r--doc/examples/timed/.gitignore5
-rw-r--r--doc/examples/timed/Makefile13
-rw-r--r--doc/examples/timed/README18
-rw-r--r--doc/examples/timed/cleanup.c8
-rw-r--r--doc/examples/timed/init.c8
-rw-r--r--doc/examples/timed/poll.c45
-rw-r--r--doc/examples/timed/write.c32
-rw-r--r--src/bus.c25
-rw-r--r--src/bus.h9
10 files changed, 140 insertions, 27 deletions
diff --git a/doc/examples/nonblocking/poll.c b/doc/examples/nonblocking/poll.c
index c918b5b..2b0c266 100644
--- a/doc/examples/nonblocking/poll.c
+++ b/doc/examples/nonblocking/poll.c
@@ -14,9 +14,9 @@ int main()
const char *message;
long long tick = 0;
t(bus_open(&bus, "/tmp/example-bus", BUS_RDONLY));
- t(bus_poll_start(&bus, BUS_NOWAIT));
+ t(bus_poll_start(&bus));
for (;;) {
- message = bus_poll(&bus);
+ message = bus_poll(&bus, BUS_NOWAIT);
if (message == NULL) {
t(errno != EAGAIN);
printf("waiting... %lli\n", ++tick);
diff --git a/doc/examples/timed/.gitignore b/doc/examples/timed/.gitignore
new file mode 100644
index 0000000..e5c1856
--- /dev/null
+++ b/doc/examples/timed/.gitignore
@@ -0,0 +1,5 @@
+cleanup
+init
+write
+poll
+
diff --git a/doc/examples/timed/Makefile b/doc/examples/timed/Makefile
new file mode 100644
index 0000000..1b1cbd3
--- /dev/null
+++ b/doc/examples/timed/Makefile
@@ -0,0 +1,13 @@
+COMMANDS = init cleanup write poll
+
+all: ${COMMANDS}
+
+%: %.c
+ ${CC} -Wall -Wextra -pedantic -std=c99 -lbus -o $@ $<
+
+clean:
+ -rm ${COMMANDS}
+
+
+.PHONY: all clean
+
diff --git a/doc/examples/timed/README b/doc/examples/timed/README
new file mode 100644
index 0000000..b0989bf
--- /dev/null
+++ b/doc/examples/timed/README
@@ -0,0 +1,18 @@
+API usage example
+
+This example shows how to use timed operations.
+
+
+
+First of, run make to build this example.
+
+To start the example run ./init.
+When you are done run ./cleanup.
+
+Running instances of ./poll will wait for new messages
+continuously, but with one second timeouts.
+
+./poll, ./init and ./cleanup are run without any
+additional arguments. ./write is run with the message
+as the second argument.
+
diff --git a/doc/examples/timed/cleanup.c b/doc/examples/timed/cleanup.c
new file mode 100644
index 0000000..00f07bc
--- /dev/null
+++ b/doc/examples/timed/cleanup.c
@@ -0,0 +1,8 @@
+#include <bus.h>
+#include <stdio.h>
+
+int main()
+{
+ return bus_unlink("/tmp/example-bus") && (perror("cleanup"), 1);
+}
+
diff --git a/doc/examples/timed/init.c b/doc/examples/timed/init.c
new file mode 100644
index 0000000..870e10d
--- /dev/null
+++ b/doc/examples/timed/init.c
@@ -0,0 +1,8 @@
+#include <bus.h>
+#include <stdio.h>
+
+int main()
+{
+ return bus_create("/tmp/example-bus", 0, NULL) && (perror("init"), 1);
+}
+
diff --git a/doc/examples/timed/poll.c b/doc/examples/timed/poll.c
new file mode 100644
index 0000000..d8c5aac
--- /dev/null
+++ b/doc/examples/timed/poll.c
@@ -0,0 +1,45 @@
+#include <bus.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define t(stmt) if (stmt) goto fail
+
+
+
+int main()
+{
+ bus_t bus;
+ const char *message;
+ long long tick = 0;
+ struct timespec timeout;
+ t(bus_open(&bus, "/tmp/example-bus", BUS_RDONLY));
+ t(bus_poll_start(&bus));
+ for (;;) {
+ t(clock_gettime(CLOCK_MONOTONIC, &timeout));
+ timeout.tv_sec += 1;
+ message = bus_poll_timed(&bus, &timeout, CLOCK_MONOTONIC);
+ if (message == NULL) {
+ t(errno != EAGAIN);
+ printf("waiting... %lli\n", ++tick);
+ sleep(1);
+ continue;
+ }
+ tick = 0;
+ message = strchr(message, ' ') + 1;
+ if (!strcmp(message, "stop"))
+ break;
+ printf("\033[01m%s\033[21m\n", message);
+ }
+ t(bus_poll_stop(&bus));
+ bus_close(&bus);
+ return 0;
+
+fail:
+ perror("poll");
+ bus_poll_stop(&bus);
+ bus_close(&bus);
+ return 1;
+}
+
diff --git a/doc/examples/timed/write.c b/doc/examples/timed/write.c
new file mode 100644
index 0000000..b6b4c16
--- /dev/null
+++ b/doc/examples/timed/write.c
@@ -0,0 +1,32 @@
+#include <bus.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#define t(stmt) if (stmt) goto fail
+
+
+
+static char message[BUS_MEMORY_SIZE];
+
+
+
+int main(int argc, char *argv[])
+{
+ bus_t bus;
+ if (argc < 2) {
+ fprintf(stderr, "%s: USAGE: %s message\n", argv[0], argv[0]);
+ return 2;
+ }
+ sprintf(message, "0 %s", argv[1]);
+ t(bus_open(&bus, "/tmp/example-bus", BUS_WRONLY));
+ t(bus_write(&bus, message, 0));
+ bus_close(&bus);
+ return 0;
+
+fail:
+ perror("write");
+ bus_close(&bus);
+ return 1;
+}
+
diff --git a/src/bus.c b/src/bus.c
index 516def1..0517f7a 100644
--- a/src/bus.c
+++ b/src/bus.c
@@ -985,14 +985,11 @@ done:
* @return 0 on success, -1 on error
*/
int
-bus_poll_start(bus_t *bus, int flags)
+bus_poll_start(bus_t *bus)
{
bus->first_poll = 1;
- bus->flags = flags;
t(release_semaphore(bus, S, SEM_UNDO));
- if (flags & BUS_NOWAIT) {
- t(release_semaphore(bus, Q, 0));
- }
+ t(release_semaphore(bus, Q, 0));
return 0;
fail:
@@ -1027,7 +1024,7 @@ bus_poll_stop(const bus_t *bus)
* @return The received message, `NULL` on error
*/
const char *
-bus_poll(bus_t *bus)
+bus_poll(bus_t *bus, int flags)
{
int state = 0, saved_errno;
if (!bus->first_poll) {
@@ -1039,19 +1036,12 @@ bus_poll(bus_t *bus)
#endif
t(release_semaphore(bus, S, SEM_UNDO)); state--;
t(acquire_semaphore(bus, W, SEM_UNDO)); state--;
- if (bus->flags & BUS_NOWAIT) {
- t(release_semaphore(bus, Q, 0));
- }
+ t(release_semaphore(bus, Q, 0));
} else {
bus->first_poll = 0;
}
state--;
- if (bus->flags & BUS_NOWAIT) {
- t(zero_semaphore(bus, Q, IPC_NOWAIT));
- } else {
- t(release_semaphore(bus, Q, 0));
- t(zero_semaphore(bus, Q, 0));
- }
+ t(zero_semaphore(bus, Q, F(BUS_NOWAIT, IPC_NOWAIT)));
return bus->message;
fail:
@@ -1087,7 +1077,7 @@ const char *bus_poll_timed(bus_t *bus, const struct timespec *timeout, clockid_t
int state = 0, saved_errno;
struct timespec delta;
if (!timeout)
- return bus_poll(bus);
+ return bus_poll(bus, 0);
if (!bus->first_poll) {
t(release_semaphore(bus, W, SEM_UNDO)); state++;
@@ -1098,13 +1088,12 @@ const char *bus_poll_timed(bus_t *bus, const struct timespec *timeout, clockid_t
#endif
t(release_semaphore(bus, S, SEM_UNDO)); state--;
t(acquire_semaphore(bus, W, SEM_UNDO)); state--;
+ t(release_semaphore(bus, Q, 0));
} else {
bus->first_poll = 0;
}
state--;
DELTA;
- t(release_semaphore_timed(bus, Q, 0, &delta));
- DELTA;
t(zero_semaphore_timed(bus, Q, 0, &delta));
return bus->message;
diff --git a/src/bus.h b/src/bus.h
index aa35c7b..9d3b436 100644
--- a/src/bus.h
+++ b/src/bus.h
@@ -107,11 +107,6 @@ typedef struct bus
*/
int first_poll;
- /**
- * Flags used for polling
- */
- int flags;
-
} bus_t;
@@ -258,7 +253,7 @@ int bus_read_timed(const bus_t *bus, int (*callback)(const char *message, void *
* the bus when `bus_poll` is called
* @return 0 on success, -1 on error
*/
-int bus_poll_start(bus_t *bus, int flags);
+int bus_poll_start(bus_t *bus);
/**
* Announce that the thread has stopped listening on the bus.
@@ -281,7 +276,7 @@ int bus_poll_stop(const bus_t *bus);
* @param bus Bus information
* @return The received message, `NULL` on error
*/
-const char *bus_poll(bus_t *bus);
+const char *bus_poll(bus_t *bus, int flags);
/**
* Wait for a message to be broadcasted on the bus.