barrier: fix up constructor error handling

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.
This commit is contained in:
David Herrmann 2014-10-02 08:31:28 +02:00
parent dda57d9143
commit fc80861622
2 changed files with 16 additions and 5 deletions

View file

@ -112,15 +112,24 @@
* 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;
}

View 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);