chiark / gitweb /
Prep v220: Apply "Fixes to user and session saving"
[elogind.git] / src / shared / barrier.c
index 4ac42d023943cd2d76d17b46f4287c9f582e8a7f..436ba9598910a861b59312effa26622f7cdee1c8 100644 (file)
 
 #include <errno.h>
 #include <fcntl.h>
-#include <limits.h>
 #include <poll.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <sys/eventfd.h>
 #include <sys/types.h>
 #include <unistd.h>
  * Returns: 0 on success, negative error code on failure.
  */
 int barrier_create(Barrier *b) {
+        _cleanup_(barrier_destroyp) Barrier *staging = b;
+        int r;
+
         assert(b);
 
-        if ((b->me = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
-            (b->them = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
-            pipe2(b->pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
-                barrier_destroy(b);
+        b->me = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+        if (b->me < 0)
+                return -errno;
+
+        b->them = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+        if (b->them < 0)
                 return -errno;
-        }
 
+        r = pipe2(b->pipe, O_CLOEXEC | O_NONBLOCK);
+        if (r < 0)
+                return -errno;
+
+        staging = NULL;
         return 0;
 }
 
@@ -132,7 +138,7 @@ int barrier_create(Barrier *b) {
  * barrier_create(). The object is released and reset to invalid
  * state. Therefore, it is safe to call barrier_destroy() multiple
  * times or even if barrier_create() failed. However, barrier must be
- * always initalized with BARRIER_NULL.
+ * always initialized with BARRIER_NULL.
  *
  * If @b is NULL, this is a no-op.
  */
@@ -169,7 +175,7 @@ void barrier_set_role(Barrier *b, unsigned int role) {
         assert(b);
         assert(role == BARRIER_PARENT || role == BARRIER_CHILD);
         /* make sure this is only called once */
-        assert(b->pipe[1] >= 0 && b->pipe[1] >= 0);
+        assert(b->pipe[0] >= 0 && b->pipe[1] >= 0);
 
         if (role == BARRIER_PARENT)
                 b->pipe[1] = safe_close(b->pipe[1]);
@@ -257,6 +263,8 @@ static bool barrier_read(Barrier *b, int64_t comp) {
                          * guarantees that exit-abortions do not overwrite real
                          * barriers. */
                         buf = BARRIER_ABORTION;
+                else
+                        continue;
 
                 /* lock if they aborted */
                 if (buf >= (uint64_t)BARRIER_ABORTION) {