summaryrefslogtreecommitdiff
path: root/src/server/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/state.c')
-rw-r--r--src/server/state.c135
1 files changed, 105 insertions, 30 deletions
diff --git a/src/server/state.c b/src/server/state.c
index 0e2afe3..c6fb2d0 100644
--- a/src/server/state.c
+++ b/src/server/state.c
@@ -11,32 +11,53 @@
#include <skalibs/djbunix.h>
#include <s6-rc/db.h>
+#include "dynstorage.h"
#include "state.h"
+static stateatom_t const stateatom_zero = STATEATOM_ZERO ;
+
+void instance_free (instance_t *ins)
+{
+ dynstorage_remove(ins->param) ;
+}
+
+int instance_new (instance_t *ins, stateatom_t const *state, char const *param) ;
+{
+ char const *s = dynstorage_add(param) ;
+ if (!s) return 0 ;
+ ins->state = state ;
+ inst->param = s ;
+ return 1 ;
+}
+
void state_free (state_t *st, uint32_t const *dbn)
{
for (s6rc_stype_t type = S6RC_STYPE_LONGRUN ; type < S6RC_STYPE_PHAIL ; type++)
{
alloc_free(st->sta[type]) ;
for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++)
+ {
+ for (size_t j = 0 ; j < genalloc_len(instance_t, st->dyn[type] + i) ; j++)
+ instance_free(genalloc_s(instance_t, st->dyn[type] + i) + j) ;
genalloc_free(instance_t, st->dyn[type] + i) ;
+ }
alloc_free(st->dyn[type]) ;
}
}
-int state_ready (state_t *st, uint32_t const *dbn)
+int state_init (state_t *st, uint32_t const *dbn)
{
s6rc_stype_t type = 0 ;
for (; type < S6RC_STYPE_PHAIL ; type++)
{
- genalloc *q ;
- stateatom_t *p = alloc(sizeof(stateatom_t) * dbn[type]) ;
- if (!p) goto err ;
- q = alloc(sizeof(genalloc) * dbn[S6RC_STYPE_PHAIL + type]) ;
- if (!q) { alloc_free(p) ; goto err ; }
- st->sta[type] = p ;
- for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) q[i] = genalloc_zero ;
- st->dyn[type] = q ;
+ st->sta[type] = alloc(sizeof(stateatom_t) * dbn[type]) ;
+ if (!st->sta[type]) goto err ;
+ st->dyn[type] = alloc(sizeof(genalloc) * dbn[S6RC_STYPE_PHAIL + type]) ;
+ if (!st->dyn[type]) { alloc_free(st->sta[type]) ; goto err ; }
+ for (uint32_t i = 0 ; i < dbn[type] ; i++)
+ st->sta[type][i] = stateatom_zero ;
+ for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++)
+ st->dyn[type][i] = genalloc_zero ;
}
return 1 ;
@@ -49,19 +70,6 @@ int state_ready (state_t *st, uint32_t const *dbn)
return 0 ;
}
-stateatom_t *state_atom (state_t const *st, s6rc_sid_t const *id)
-{
- if (id->param)
- {
- size_t n = genalloc_len(instance_t, st->dyn[id->stype] + id->i) ;
- instance_t *instances = genalloc_s(instance_t, st->dyn[id->stype] + id->i) ;
- for (size_t i = 0 ; i < n ; i++)
- if (!strcmp(id->param, instances[i].param)) return &instances[i].state ;
- return 0 ;
- }
- else return st->sta[id->stype] + id->i ;
-}
-
static int atom_write (buffer *b, stateatom_t const *state)
{
char c = state->wanted | (state->current << 1) | (state->transitioning << 2) ;
@@ -82,15 +90,10 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn)
buffer_init(&b, &buffer_write, fd, buf, 1024) ;
for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++)
- {
- char pack[4] ;
- uint32_pack_big(pack, dbn[type]) ;
- if (buffer_put(&b, pack, 4) < 4) goto err ;
- }
- for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++)
- {
for (uint32_t i = 0 ; i < dbn[type] ; i++)
if (!atom_write(&b, st->sta[type] + i)) goto err ;
+
+ for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++)
for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++)
{
uint32_t n = genalloc_len(instance_t, st->dyn[type] + i) ;
@@ -107,7 +110,6 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn)
if (buffer_put(&b, p[j].param, len+1) < len+1) goto err ;
}
}
- }
if (!buffer_flush(&b)) goto err ;
fd_close(fd) ;
@@ -120,3 +122,76 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn)
unlink_void(fn) ;
return 0 ;
}
+
+static int atom_read (buffer *b, stateatom_t *state)
+{
+ char c ;
+ if (buffer_get(b, &c, 1) < 1) return 0 ;
+ state->wanted = c & 1 ;
+ state->current = !!(c & 2) ;
+ state->transitioning = !!(c & 4) ;
+ return 1 ;
+}
+
+int state_read (char const *file, state_t *st, uint32_t const *dbn)
+{
+ int fd ;
+ buffer b ;
+ char buf[1024] ;
+ if (!state_init(st, dbn)) return 0 ;
+ fd = openc_read(file) ;
+ if (fd == -1) goto err0 ;
+ buffer_init(&b, &buffer_read, fd, buf, 1024) ;
+
+ for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++)
+ for (uint32_t i = 0 ; i < dbn[type] ; i++)
+ if (!atom_read(&b, st->sta[type] + i)) goto err ;
+
+ for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++)
+ for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++)
+ {
+ uint32_t n ;
+ char pack[4] ;
+ if (buffer_get(&b, pack, 4) < 4) goto err ;
+ uint32_unpack_big(pack, &n) ;
+ if (!genalloc_ready(instance_t, st->dyn[type] + i, n)) goto err ;
+ for (uint32_t j = 0 ; i < n ; j++)
+ {
+ uint32_t len ;
+ instance_t *ins = genalloc_s(instance_t, st->dyn[type] + i) + j ;
+ if (!atom_read(&b, &ins->state)) goto err ;
+ if (buffer_get(&b, pack, 4) < 4) goto err ;
+ uint32_unpack_big(pack, &len) ;
+ {
+ char param[len + 1] ;
+ if (buffer_get(&b, param, len + 1) < len + 1) goto err ;
+ if (param[len]) { errno = EINVAL ; goto err ; }
+ ins->param = dynstorage_add(param) ;
+ if (!ins_param) goto err ;
+ }
+ }
+ genalloc_setlen(instance_t, st->dyn[type] + i, n) ;
+ }
+
+ fd_close(fd) ;
+ return 1 ;
+
+ err:
+ fd_close(fd) ;
+ err0:
+ state_free(st, dbn) ;
+ return 0 ;
+}
+
+stateatom_t *state_atom (state_t const *st, s6rc_sid_t const *id)
+{
+ if (id->param)
+ {
+ size_t n = genalloc_len(instance_t, st->dyn[id->stype] + id->i) ;
+ instance_t *instances = genalloc_s(instance_t, st->dyn[id->stype] + id->i) ;
+ for (size_t i = 0 ; i < n ; i++)
+ if (!strcmp(id->param, instances[i].param)) return &instances[i].state ;
+ return 0 ;
+ }
+ else return st->sta[id->stype] + id->i ;
+}