From 0445f2a3590f67441602a05fe3924ab677c79ff0 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 14 Jun 2017 04:09:00 +0000 Subject: Add ftrigr_checksa(), rewrite s6_svlisten_loop() around it - Fixes the race condition hit by permanent failure, i.e. two ftrig events close to each other - Requires storing the sequence of events client-side, so an additional stralloc, bleh - The visible struct ftrigr_s changes, so a major bump is needed -> prepare for 2.6.0.0 - ftrigr_check() is now a trivial wrapper around ftrigr_checksa() --- src/supervision/s6_svlisten_loop.c | 41 ++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'src/supervision') diff --git a/src/supervision/s6_svlisten_loop.c b/src/supervision/s6_svlisten_loop.c index 5c55c81..c98fe83 100644 --- a/src/supervision/s6_svlisten_loop.c +++ b/src/supervision/s6_svlisten_loop.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,10 @@ int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tai { iopause_fd x[2] = { { .fd = ftrigr_fd(&foo->a), .events = IOPAUSE_READ }, { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } } ; unsigned int e = 0 ; - while (!got(foo, wantup, wantready, or)) + stralloc sa = STRALLOC_ZERO ; + + if (got(foo, wantup, wantready, or)) return 0 ; + for (;;) { int r = iopause_g(x, 1 + (spfd >= 0), deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; @@ -60,29 +64,36 @@ int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tai if (ftrigr_update(&foo->a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; for (; i < foo->n ; i++) { - char what ; - int r = ftrigr_check(&foo->a, foo->ids[i], &what) ; + sa.len = 0 ; + r = ftrigr_checksa(&foo->a, foo->ids[i], &sa) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ; - if (r) + else if (r) { - if (what == 'O') + size_t j = 0 ; + for (; j < sa.len ; j++) { - if (wantup) + if (sa.s[j] == 'O') { - bitarray_poke(foo->upstate, i, wantup) ; - bitarray_poke(foo->readystate, i, wantready) ; - e++ ; + if (wantup) + { + bitarray_poke(foo->upstate, i, wantup) ; + bitarray_poke(foo->readystate, i, wantready) ; + e++ ; + } } - } - else - { - unsigned int d = byte_chr("dDuU", 4, what) ; - bitarray_poke(foo->upstate, i, d & 2) ; - bitarray_poke(foo->readystate, i, d & 1) ; + else + { + unsigned int d = byte_chr("dDuU", 4, sa.s[j]) ; + bitarray_poke(foo->upstate, i, d & 2) ; + bitarray_poke(foo->readystate, i, d & 1) ; + } + if (got(foo, wantup, wantready, or)) goto gotit ; } } } } } + gotit: + stralloc_free(&sa) ; return e ; } -- cgit v1.2.3