about summary refs log tree commit diff
path: root/src/libs6
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/libs6
parentf287ac765101f21b530f1a9886e06976c165c922 (diff)
downloads6-0445f2a3590f67441602a05fe3924ab677c79ff0.tar.gz
s6-0445f2a3590f67441602a05fe3924ab677c79ff0.tar.xz
s6-0445f2a3590f67441602a05fe3924ab677c79ff0.zip
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/libs6')
-rw-r--r--src/libs6/deps-lib/s61
-rw-r--r--src/libs6/ftrigr_check.c39
-rw-r--r--src/libs6/ftrigr_checksa.c45
-rw-r--r--src/libs6/ftrigr_subscribe.c4
-rw-r--r--src/libs6/ftrigr_unsubscribe.c2
-rw-r--r--src/libs6/ftrigr_update.c5
6 files changed, 63 insertions, 33 deletions
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 65062e1..ace5a05 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -1,5 +1,6 @@
 ftrigr1_zero.o
 ftrigr_check.o
+ftrigr_checksa.o
 ftrigr_end.o
 ftrigr_start.o
 ftrigr_startf.o
diff --git a/src/libs6/ftrigr_check.c b/src/libs6/ftrigr_check.c
index 0a7fcdc..30be701 100644
--- a/src/libs6/ftrigr_check.c
+++ b/src/libs6/ftrigr_check.c
@@ -1,39 +1,20 @@
 /* ISC license. */
 
 #include <errno.h>
-#include <skalibs/gensetdyn.h>
+#include <skalibs/stralloc.h>
 #include <s6/ftrigr.h>
 
 int ftrigr_check (ftrigr_t *a, uint16_t id, char *c)
 {
-  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)
+  stralloc sa = STRALLOC_ZERO ;
+  int r = ftrigr_checksa(a, id, &sa) ;
+
+  if (r && sa.len)
   {
-    case FR1STATE_WAITACKDATA :
-    {
-      *c = p->what ;
-      *p = ftrigr1_zero ;
-      gensetdyn_delete(&a->data, id) ;
-      return 1 ;
-    }
-    case FR1STATE_LISTENING :
-    {
-      unsigned int r = p->count ;
-      if (r) *c = p->what ;
-      p->count = 0 ;
-      return (int)r ;
-    }
-    case FR1STATE_WAITACK :
-    {
-      errno = p->what ;
-      *p = ftrigr1_zero ;
-      gensetdyn_delete(&a->data, id) ;
-      return -1 ;
-    }
-    default: return (errno = EINVAL, -1) ;
+    int e = errno ;
+    *c = sa.s[sa.len - 1] ;
+    stralloc_free(&sa) ;
+    errno = e ;
   }
-  return 0 ;
+  return r ;
 }
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 <errno.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/gensetdyn.h>
+#include <s6/ftrigr.h>
+
+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 ;
+}
diff --git a/src/libs6/ftrigr_subscribe.c b/src/libs6/ftrigr_subscribe.c
index 3766d35..cbbde1e 100644
--- a/src/libs6/ftrigr_subscribe.c
+++ b/src/libs6/ftrigr_subscribe.c
@@ -7,6 +7,7 @@
 #include <skalibs/uint16.h>
 #include <skalibs/uint32.h>
 #include <skalibs/tai.h>
+#include <skalibs/stralloc.h>
 #include <skalibs/gensetdyn.h>
 #include <skalibs/skaclient.h>
 #include <s6/ftrigr.h>
@@ -45,8 +46,7 @@ uint16_t ftrigr_subscribe (ftrigr_t *a, char const *path, char const *re, uint32
     ftrigr1_t *p = GENSETDYN_P(ftrigr1_t, &a->data, i) ;
     p->options = options ;
     p->state = FR1STATE_LISTENING ;
-    p->count = 0 ;
-    p->what = 0 ;
+    p->what = stralloc_zero ;
   }
   return (uint16_t)(i+1) ;
 }
diff --git a/src/libs6/ftrigr_unsubscribe.c b/src/libs6/ftrigr_unsubscribe.c
index 4428b72..a96ddb0 100644
--- a/src/libs6/ftrigr_unsubscribe.c
+++ b/src/libs6/ftrigr_unsubscribe.c
@@ -2,6 +2,7 @@
 
 #include <errno.h>
 #include <skalibs/uint16.h>
+#include <skalibs/stralloc.h>
 #include <skalibs/gensetdyn.h>
 #include <skalibs/skaclient.h>
 #include <s6/ftrigr.h>
@@ -30,6 +31,7 @@ int ftrigr_unsubscribe (ftrigr_t *a, uint16_t i, tain_t const *deadline, tain_t
     if (!skaclient_send(&a->connection, pack, 3, &skaclient_default_cb, &err, deadline, stamp)) return 0 ;
     if (err) return (errno = err, 0) ;
   }
+  stralloc_free(&p->what) ;
   *p = ftrigr1_zero ;
   return gensetdyn_delete(&a->data, i) ;
 }
diff --git a/src/libs6/ftrigr_update.c b/src/libs6/ftrigr_update.c
index 52f79b9..f97535d 100644
--- a/src/libs6/ftrigr_update.c
+++ b/src/libs6/ftrigr_update.c
@@ -35,12 +35,14 @@ static int msghandler (unixmessage_t const *m, void *context)
   switch (m->s[2])
   {
     case 'd' :
+      if (!stralloc_catb(&p->what, m->s + 3, 1)) return 0 ;
       p->state = FR1STATE_WAITACK ;
       break ;
     case '!' :
+      if (!stralloc_catb(&p->what, m->s + 3, 1)) return 0 ;
       if (p->options & FTRIGR_REPEAT)
       {
-        if (p->count++
+        if (p->what.len > 1
          && appears(id+1, genalloc_s(uint16_t, &a->list), genalloc_len(uint16_t, &a->list)))
           addit = 0 ;
       }
@@ -48,7 +50,6 @@ static int msghandler (unixmessage_t const *m, void *context)
       break ;
     default : return (errno = EPROTO, 0) ;
   }
-  p->what = m->s[3] ;
   if (addit)
   {
     id++ ; genalloc_append(uint16_t, &a->list, &id) ;