chiark / gitweb /
barrier: fix up constructor error handling
authorDavid Herrmann <dh.herrmann@gmail.com>
Thu, 2 Oct 2014 06:31:28 +0000 (08:31 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Thu, 2 Oct 2014 06:40:43 +0000 (08:40 +0200)
We cannot rely on "errno" to be non-zero on failure, if we perform
multiple glibc calls. That is, if the first eventfd() call fails, but the
second succeeds, we cleanup the barrier but return 0.

Fix this by always testing the return value immediately. This should also
fix all the coverity warnings.

src/shared/barrier.c
src/shared/barrier.h

index 4a5544de27d309f0593c34d5fc4e1ccba06d0985..f65363a67b11ab9bc625a21b47aeb5caa182f6c5 100644 (file)
  * 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;
 }
 
index 53b4439fb2b5c78d03960dbc97e32914e463f670..c55e3113448ff3e919b0804de201c3a9742d6398 100644 (file)
@@ -62,6 +62,8 @@ struct Barrier {
 int barrier_create(Barrier *obj);
 void barrier_destroy(Barrier *b);
 
+DEFINE_TRIVIAL_CLEANUP_FUNC(Barrier*, barrier_destroy);
+
 void barrier_set_role(Barrier *b, unsigned int role);
 
 bool barrier_place(Barrier *b);