diff options
author | Leah Neukirchen <leah@vuxu.org> | 2020-06-26 19:00:05 +0200 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2020-06-26 23:46:40 +0200 |
commit | ba968f2161ffb4e936c283487249ea28601964c4 (patch) | |
tree | 2c44585d978dfd1baace908ccd8636df5729ee3c | |
parent | 7013b5e384b74bc425f10c88b6f78e3a7a4fd39e (diff) | |
download | redo-c-ba968f2161ffb4e936c283487249ea28601964c4.tar.gz redo-c-ba968f2161ffb4e936c283487249ea28601964c4.tar.xz redo-c-ba968f2161ffb4e936c283487249ea28601964c4.zip |
use blocking/nonblocking reads instead of poll(2) v0.2
Previously, we used a blocking fd for the token pipe and used poll(2) to see if anything could be read right now in try_procure(). However, there is a race between poll(2) and the subsequent blocking read(2), which can result in processes deadlocking when multiple instances of redo poll at the same time. Instead, we now make the fd nonblocking when needed, so that the read either reads or returns immediately if there is nothing to read. Closes #3. Closes: #4 [via git-merge-pr]
-rw-r--r-- | redo.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/redo.c b/redo.c index f482023..ad8b156 100644 --- a/redo.c +++ b/redo.c @@ -34,7 +34,6 @@ todo: #include <errno.h> #include <fcntl.h> #include <inttypes.h> -#include <poll.h> #include <stdarg.h> #include <stdint.h> #include <stdio.h> @@ -739,19 +738,13 @@ try_procure() implicit_jobs--; return 1; } else { - struct pollfd p; - if (poolrd_fd < 0) return 0; - p.fd = poolrd_fd; - p.events = POLLIN; + fcntl(poolrd_fd, F_SETFL, O_NONBLOCK); - if (poll(&p, 1, 0) > 0 && p.revents & POLLIN) { - char buf[1]; - return read(poolrd_fd, &buf, 1) > 0; - } - return 0; + char buf[1]; + return read(poolrd_fd, &buf, 1) > 0; } } @@ -762,6 +755,8 @@ procure() implicit_jobs--; return 1; } else { + fcntl(poolrd_fd, F_SETFL, 0); // clear O_NONBLOCK + char buf[1]; return read(poolrd_fd, &buf, 1) > 0; } |