summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-01-30 12:25:04 -0800
committerKeith Packard <keithp@keithp.com>2014-01-30 12:25:04 -0800
commit8c88e071c5cefa1559989d0292cdfba6b438793c (patch)
tree81ecd3e1e848aaf9302768d450f2b61ba76b56c1
parent8db31931172c538553e17c4dd9bf4975ead5c59b (diff)
Fencing using pipes. Not used in practice
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--pipefence.c112
1 files changed, 112 insertions, 0 deletions
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 <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/eventfd.h>
+#include <poll.h>
+
+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;
+}