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/libs6/ftrigr_checksa.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/libs6/ftrigr_checksa.c (limited to 'src/libs6/ftrigr_checksa.c') diff --git a/src/libs6/ftrigr_checksa.c b/src/libs6/ftrigr_checksa.c new file mode 100644 index 0000000..6573182 --- /dev/null +++ b/src/libs6/ftrigr_checksa.c @@ -0,0 +1,45 @@ +/* ISC license. */ + +#include +#include +#include +#include + +int ftrigr_checksa (ftrigr_t *a, uint16_t id, stralloc *sa) +{ + ftrigr1_t *p ; + if (!id--) return (errno = EINVAL, -1) ; + p = GENSETDYN_P(ftrigr1_t, &a->data, id) ; + if (!p) return (errno = EINVAL, -1) ; + switch (p->state) + { + case FR1STATE_WAITACKDATA : + { + if (!stralloc_catb(sa, p->what.s, p->what.len)) return -1 ; + stralloc_free(&p->what) ; + *p = ftrigr1_zero ; + gensetdyn_delete(&a->data, id) ; + return 1 ; + } + case FR1STATE_LISTENING : + { + if (!p->what.len) break ; + if (!stralloc_catb(sa, p->what.s, p->what.len)) return -1 ; + p->what.len = 0 ; + return 1 ; + } + case FR1STATE_WAITACK : + { + int e ; + if (!stralloc_catb(sa, p->what.s, p->what.len - 1)) return -1 ; + e = p->what.s[p->what.len - 1] ; + stralloc_free(&p->what) ; + *p = ftrigr1_zero ; + gensetdyn_delete(&a->data, id) ; + errno = e ; + return -1 ; + } + default: return (errno = EINVAL, -1) ; + } + return 0 ; +} -- cgit v1.2.3