From 8c88e071c5cefa1559989d0292cdfba6b438793c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 30 Jan 2014 12:25:04 -0800 Subject: Fencing using pipes. Not used in practice Signed-off-by: Keith Packard --- pipefence.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 pipefence.c diff --git a/pipefence.c b/pipefence.c new file mode 100644 index 0000000..a62517b --- /dev/null +++ b/pipefence.c @@ -0,0 +1,112 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +int +event_fence_create(void) +{ + return eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK); +} + +int +event_fence_await(int fd) +{ + struct pollfd fds = { .fd = fd, .events = POLLIN }; + int ret; + + for (;;) { + ret = poll (&fds, 1, -1); + if (ret < 0) + return -errno; + if (ret > 0 && fds.revents & POLLIN) + return 1; + } +} + +int +event_fence_test(int fd) +{ + struct pollfd fds = { .fd = fd, .events = POLLIN }; + int ret; + + ret = poll (&fds, 1, 0); + if (ret < 0) + return -errno; + if (ret > 0 && fds.revents & POLLIN) + return 1; + return 0; +} + +int +event_fence_trigger(int fd) +{ + uint64_t v = 1; + return write (fd, &v, sizeof (v)); +} + +int +event_fence_reset(int fd) +{ + int ret; + uint64_t v; + + ret = read(fd, &v, sizeof (v)); + if (ret == -1 && errno == EAGAIN) + ret = 0; + return ret; +} + +int main(int argc, char **argv) { + int fence = event_fence_create(); + int i; + + switch (fork()) { + case 0: + for (;;) { + printf ("await fence\n"); + if (event_fence_await(fence) < 0) { + printf ("waiter done\n"); + break; + } + printf ("reset fence\n"); + event_fence_reset(fence); + } + break; + case -1: + break; + default: + for (i = 0; i < 10; i++) { + sleep(1); + printf ("trigger fence\n"); + event_fence_trigger(fence); + } + printf ("trigger done\n"); + break; + } + return 0; +} -- cgit v1.2.3