diff options
Diffstat (limited to 'src/server/state.c')
-rw-r--r-- | src/server/state.c | 135 |
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 ; +} |