summaryrefslogtreecommitdiff
path: root/src/supervision
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-06-14 04:09:00 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-06-14 04:09:00 +0000
commit0445f2a3590f67441602a05fe3924ab677c79ff0 (patch)
tree1a011697fbd92ca53468efe019c8c93c364ad6a8 /src/supervision
parentf287ac765101f21b530f1a9886e06976c165c922 (diff)
downloads6-0445f2a3590f67441602a05fe3924ab677c79ff0.tar.xz
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()
Diffstat (limited to 'src/supervision')
-rw-r--r--src/supervision/s6_svlisten_loop.c41
1 files changed, 26 insertions, 15 deletions
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 <skalibs/bitarray.h>
#include <skalibs/strerr2.h>
#include <skalibs/iopause.h>
+#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <s6/ftrigr.h>
#include <s6/s6-supervise.h>
@@ -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 ;
}