diff options
| -rw-r--r-- | src/include/skalibs/sassserver.h | 32 | ||||
| -rw-r--r-- | src/libunixonacid/sassserver.c | 158 |
2 files changed, 102 insertions, 88 deletions
diff --git a/src/include/skalibs/sassserver.h b/src/include/skalibs/sassserver.h index f43ea4c..4294e59 100644 --- a/src/include/skalibs/sassserver.h +++ b/src/include/skalibs/sassserver.h @@ -8,6 +8,8 @@ #include <skalibs/tai.h> #include <skalibs/iopause.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avltree.h> typedef int sassserver_send_func (void *, uint32_t, uint32_t, uint32_t, char const *, size_t) ; typedef sassserver_send_func *sassserver_send_func_ref ; @@ -15,15 +17,27 @@ typedef sassserver_send_func *sassserver_send_func_ref ; typedef void sassserver_cancel_func (void *) ; typedef sassserver_cancel_func *sassserver_cancel_func_ref ; -extern void sassserver_init (char const *, char const *, sassserver_send_func_ref, sassserver_cancel_func_ref, size_t, tain const *, tain *stamp) ; -#define sassserver_init_g(banner1, banner2, sendf, cancelf, esize, deadline) sassserver_init(banner1, banner2, sendf, cancelf, esize, (deadline), &STAMP) -extern unsigned int sassserver_prepare_iopause (iopause_fd *, tain *) ; -extern void sassserver_timeout (void) ; -extern int sassserver_event (iopause_fd const *) ; -extern void *sassserver_data (uint32_t) ; +typedef struct sassserver_s sassserver, *sassserver_ref ; +struct sassserver_s +{ + sassserver_send_func_ref sendf ; + sassserver_cancel_func_ref cancelf ; + size_t datasize ; + gensetdyn queries ; + avltree by_deadline ; + avltree by_id ; +} ; +#define SASSSERVER_ZERO { .sendf = 0, .cancelf = 0, .datasize = 0, .queries = GENSETDYN_ZERO, .by_deadline = AVLTREE_ZERO, .by_id = AVLTREE_ZERO } -extern void sassserver_async_failure (uint32_t, int) ; -extern void sassserver_async_success (uint32_t, uint32_t, char const *, size_t) ; -extern void sassserver_async_successv (uint32_t, uint32_t, struct iovec const *, unsigned int) ; +extern void sassserver_init (sassserver *, char const *, char const *, sassserver_send_func_ref, sassserver_cancel_func_ref, size_t, tain const *, tain *stamp) ; +#define sassserver_init_g(a, banner1, banner2, sendf, cancelf, esize, deadline) sassserver_init(a, banner1, banner2, sendf, cancelf, esize, (deadline), &STAMP) +extern unsigned int sassserver_prepare_iopause (sassserver const *, iopause_fd *, tain *) ; +extern void sassserver_timeout (sassserver *) ; +extern int sassserver_event (sassserver *, iopause_fd const *) ; +extern void *sassserver_data (sassserver const *, uint32_t) ; + +extern void sassserver_async_failure (sassserver *, uint32_t, int) ; +extern void sassserver_async_success (sassserver *, uint32_t, uint32_t, char const *, size_t) ; +extern void sassserver_async_successv (sassserver *, uint32_t, uint32_t, struct iovec const *, unsigned int) ; #endif diff --git a/src/libunixonacid/sassserver.c b/src/libunixonacid/sassserver.c index f009c1a..a165c0b 100644 --- a/src/libunixonacid/sassserver.c +++ b/src/libunixonacid/sassserver.c @@ -18,6 +18,9 @@ #include <skalibs/sass.h> #include <skalibs/sassserver.h> + + /* Private */ + typedef struct sassserver_query_s sassserver_query, sassserver_query_ref ; struct sassserver_query_s { @@ -26,23 +29,13 @@ struct sassserver_query_s void *data ; } ; -static sassserver_send_func_ref sassserver_sendf ; -static sassserver_cancel_func_ref sassserver_cancelf ; -static size_t sassserver_datasize ; - -static gensetdyn sassserver_queries = GENSETDYN_INIT(sassserver_query, 8, 3, 8) ; -#define SASSSERVER_QUERY(i) GENSETDYN_P(sassserver_query, &sassserver_queries, (i)) +#define SASSSERVER_QUERY(a, i) GENSETDYN_P(sassserver_query, &(a)->queries, i) static void *sassserver_deadline_dtok (uint32_t d, void *aux) { return &GENSETDYN_P(sassserver_query, (gensetdyn *)aux, d)->deadline ; } -void *sassserver_data (uint32_t handle) -{ - return SASSSERVER_QUERY(handle)->data ; -} - static int sassserver_deadline_cmp (void const *a, void const *b, void *aux) { tain const *aa = a ; @@ -51,8 +44,6 @@ static int sassserver_deadline_cmp (void const *a, void const *b, void *aux) return tain_less(aa, bb) ? -1 : tain_less(bb, aa) ; } -static avltree sassserver_by_deadline = AVLTREE_INIT(8, 3, 8, &sassserver_deadline_dtok, &sassserver_deadline_cmp, &sassserver_queries) ; - static void *sassserver_id_dtok (uint32_t d, void *aux) { return &GENSETDYN_P(sassserver_query, (gensetdyn *)aux, d)->id ; @@ -66,8 +57,6 @@ static int sassserver_id_cmp (void const *a, void const *b, void *aux) return *aa < *bb ? -1 : *aa > *bb ; } -static avltree sassserver_by_id = AVLTREE_INIT(8, 3, 8, &sassserver_id_dtok, &sassserver_id_cmp, &sassserver_queries) ; - static void sassserver_sync_answer (int e) { char pack[4] ; @@ -76,57 +65,27 @@ static void sassserver_sync_answer (int e) strerr_diefu1sys(111, "textmessage_put") ; } -static void sassserver_remove (uint32_t handle) -{ - sassserver_query *p = SASSSERVER_QUERY(handle) ; - avltree_delete(&sassserver_by_deadline, &p->deadline) ; - avltree_delete(&sassserver_by_id, &p->id) ; - gensetdyn_delete(&sassserver_queries, handle) ; -} - -void sassserver_async_failure (uint32_t handle, int e) -{ - sassserver_query *p = SASSSERVER_QUERY(handle) ; - char pack[8] ; - uint32_pack_big(pack, p->id) ; - uint32_pack_big(pack + 4, (uint32_t)e) ; - if (!textmessage_put(textmessage_sender_x, pack, 8)) - strerr_diefu1sys(111, "textmessage_put") ; - sassserver_remove(handle) ; -} - -void sassserver_async_successv (uint32_t handle, uint32_t flags, struct iovec const *v, unsigned int n) -{ - sassserver_query *p = SASSSERVER_QUERY(handle) ; - char pack[8] = "\0\0\0\0\0\0\0" ; - struct iovec vv[n+1] ; - vv[0].iov_base = pack ; vv[0].iov_len = 8 ; - for (unsigned int i = 0 ; i < n ; i++) vv[i+1] = v[i] ; - uint32_pack_big(pack, p->id) ; - if (!textmessage_putv(textmessage_sender_x, vv, n+1)) - strerr_diefu1sys(111, "textmessage_putv") ; - if (!(flags & SASS_FLAGS_KEEP)) sassserver_remove(handle) ; -} - -void sassserver_async_success (uint32_t handle, uint32_t flags, char const *s, size_t len) +static void sassserver_remove (sassserver *a, uint32_t handle) { - struct iovec v = { .iov_base = (char *)s, .iov_len = len } ; - sassserver_async_successv(handle, flags, &v, 1) ; + sassserver_query *p = SASSSERVER_QUERY(a, handle) ; + avltree_delete(&a->by_deadline, &p->deadline) ; + avltree_delete(&a->by_id, &p->id) ; + gensetdyn_delete(&a->queries, handle) ; } -static inline void sassserver_uniquify (tain *deadline) +static inline void sassserver_uniquify (sassserver const *a, tain *deadline) { static tain const nanosec = { .sec = TAI_ZERO, .nano = 1 } ; uint32_t dummy ; - while (avltree_search(&sassserver_by_deadline, deadline, &dummy)) + while (avltree_search(&a->by_deadline, deadline, &dummy)) tain_add(deadline, deadline, &nanosec) ; } static int sassserver_parse_protocol (struct iovec const *v, void *aux) { + sassserver *a = aux ; char const *s = v->iov_base ; size_t vlen = v->iov_len ; - (void)aux ; if (vlen-- < 5) strerr_dief1x(100, "invalid client request") ; switch (*s++) { @@ -135,9 +94,9 @@ static int sassserver_parse_protocol (struct iovec const *v, void *aux) uint32_t handle, id ; if (vlen != 4) strerr_dief1x(100, "invalid client request") ; uint32_unpack_big(s, &id) ; - if (!avltree_search(&sassserver_by_id, &id, &handle)) sassserver_sync_answer(EINVAL) ; - (*sassserver_cancelf)(SASSSERVER_QUERY(handle)->data) ; - sassserver_remove(handle) ; + if (!avltree_search(&a->by_id, &id, &handle)) sassserver_sync_answer(EINVAL) ; + (*a->cancelf)(SASSSERVER_QUERY(a, handle)->data) ; + sassserver_remove(a, handle) ; sassserver_sync_answer(0) ; break ; } @@ -151,8 +110,8 @@ static int sassserver_parse_protocol (struct iovec const *v, void *aux) uint32_t len ; int e ; if (vlen < 20) strerr_dief1x(100, "invalid client request") ; - if (!gensetdyn_new(&sassserver_queries, &handle)) strerr_diefu1sys(111, "gensetdyn_new") ; - p = SASSSERVER_QUERY(handle) ; + if (!gensetdyn_new(&a->queries, &handle)) strerr_diefu1sys(111, "gensetdyn_new") ; + p = SASSSERVER_QUERY(a, handle) ; uint32_unpack_big(s, &p->id) ; s += 4 ; vlen -= 4 ; uint32_unpack_big(s, &flags) ; s += 4 ; vlen -= 4 ; uint32_unpack_big(s, &timeout) ; s += 4 ; vlen -= 4 ; @@ -165,16 +124,16 @@ static int sassserver_parse_protocol (struct iovec const *v, void *aux) tain_add_g(&p->deadline, &p->deadline) ; } else tain_add_g(&p->deadline, &tain_infinite_relative) ; - sassserver_uniquify(&p->deadline) ; - if (!avltree_insert(&sassserver_by_deadline, handle)) strerr_diefu1sys(111, "avltree_insert") ; - if (!avltree_insert(&sassserver_by_id, handle)) strerr_diefu1sys(111, "avltree_insert") ; + sassserver_uniquify(a, &p->deadline) ; + if (!avltree_insert(&a->by_deadline, handle)) strerr_diefu1sys(111, "avltree_insert") ; + if (!avltree_insert(&a->by_id, handle)) strerr_diefu1sys(111, "avltree_insert") ; if (!p->data) { - p->data = alloc(sassserver_datasize) ; + p->data = alloc(a->datasize) ; if (!p->data) strerr_diefu1sys(111, "alloc") ; } - e = (*sassserver_sendf)(p->data, handle, flags, opcode, s, len) ; - if (e) sassserver_remove(handle) ; + e = (*a->sendf)(p->data, handle, flags, opcode, s, len) ; + if (e) sassserver_remove(a, handle) ; sassserver_sync_answer(e) ; break ; } @@ -183,18 +142,59 @@ static int sassserver_parse_protocol (struct iovec const *v, void *aux) return 1 ; } -void sassserver_init (char const *banner1, char const *banner2, sassserver_send_func_ref sendf, sassserver_cancel_func_ref cancelf, size_t datasize, tain const *deadline, tain *stamp) + + /* Public */ + +void *sassserver_data (sassserver const *a, uint32_t handle) +{ + return SASSSERVER_QUERY(a, handle)->data ; +} + +void sassserver_async_failure (sassserver *a, uint32_t handle, int e) +{ + sassserver_query *p = SASSSERVER_QUERY(a, handle) ; + char pack[8] ; + uint32_pack_big(pack, p->id) ; + uint32_pack_big(pack + 4, (uint32_t)e) ; + if (!textmessage_put(textmessage_sender_x, pack, 8)) + strerr_diefu1sys(111, "textmessage_put") ; + sassserver_remove(a, handle) ; +} + +void sassserver_async_successv (sassserver *a, uint32_t handle, uint32_t flags, struct iovec const *v, unsigned int n) +{ + sassserver_query *p = SASSSERVER_QUERY(a, handle) ; + char pack[8] = "\0\0\0\0\0\0\0" ; + struct iovec vv[n+1] ; + vv[0].iov_base = pack ; vv[0].iov_len = 8 ; + for (unsigned int i = 0 ; i < n ; i++) vv[i+1] = v[i] ; + uint32_pack_big(pack, p->id) ; + if (!textmessage_putv(textmessage_sender_x, vv, n+1)) + strerr_diefu1sys(111, "textmessage_putv") ; + if (!(flags & SASS_FLAGS_KEEP)) sassserver_remove(a, handle) ; +} + +void sassserver_async_success (sassserver *a, uint32_t handle, uint32_t flags, char const *s, size_t len) +{ + struct iovec v = { .iov_base = (char *)s, .iov_len = len } ; + sassserver_async_successv(a, handle, flags, &v, 1) ; +} + +void sassserver_init (sassserver *a, char const *banner1, char const *banner2, sassserver_send_func_ref sendf, sassserver_cancel_func_ref cancelf, size_t datasize, tain const *deadline, tain *stamp) { if (!textclient_server_01x_init(banner1, strlen(banner1), banner2, strlen(banner2), deadline, stamp)) strerr_diefu1sys(111, "sync with client") ; - sassserver_sendf = sendf ; - sassserver_cancelf = cancelf ; + a->sendf = sendf ; + a->cancelf = cancelf ; + gensetdyn_init(&a->queries, sizeof(sassserver_query), 8, 3, 8) ; + avltree_init(&a->by_deadline, 8, 3, 8, &sassserver_deadline_dtok, &sassserver_deadline_cmp, &a->queries) ; + avltree_init(&a->by_id, 8, 3, 8, &sassserver_id_dtok, &sassserver_id_cmp, &a->queries) ; } -unsigned int sassserver_prepare_iopause (iopause_fd *x, tain *deadline) +unsigned int sassserver_prepare_iopause (sassserver const *a, iopause_fd *x, tain *deadline) { uint32_t i ; - if (avltree_min(&sassserver_by_deadline, &i)) tain_earliest1(deadline, &SASSSERVER_QUERY(i)->deadline) ; + if (avltree_min(&a->by_deadline, &i)) tain_earliest1(deadline, &SASSSERVER_QUERY(a, i)->deadline) ; x[0].fd = 0 ; x[0].events = IOPAUSE_READ ; x[1].fd = 1 ; @@ -204,22 +204,22 @@ unsigned int sassserver_prepare_iopause (iopause_fd *x, tain *deadline) return 3 ; } -void sassserver_timeout (void) +void sassserver_timeout (sassserver *a) { uint32_t i ; - while (avltree_min(&sassserver_by_deadline, &i)) + while (avltree_min(&a->by_deadline, &i)) { - sassserver_query *p = SASSSERVER_QUERY(i) ; + sassserver_query *p = SASSSERVER_QUERY(a, i) ; if (tain_future(&p->deadline)) break ; - avltree_delete(&sassserver_by_deadline, &p->deadline) ; - avltree_delete(&sassserver_by_id, &p->id) ; - (*sassserver_cancelf)(p->data) ; - sassserver_async_failure(p->id, ETIMEDOUT) ; - gensetdyn_delete(&sassserver_queries, i) ; + avltree_delete(&a->by_deadline, &p->deadline) ; + avltree_delete(&a->by_id, &p->id) ; + (*a->cancelf)(p->data) ; + sassserver_async_failure(a, p->id, ETIMEDOUT) ; + gensetdyn_delete(&a->queries, i) ; } } -int sassserver_event (iopause_fd const *x) +int sassserver_event (sassserver *a, iopause_fd const *x) { if (x[1].revents & IOPAUSE_WRITE) if (!textmessage_sender_flush(textmessage_sender_1) && !error_isagain(errno)) @@ -230,7 +230,7 @@ int sassserver_event (iopause_fd const *x) if (!textmessage_receiver_isempty(textmessage_receiver_0) || x[0].revents & IOPAUSE_READ) { - if (textmessage_handle(textmessage_receiver_0, &sassserver_parse_protocol, 0) == -1) + if (textmessage_handle(textmessage_receiver_0, &sassserver_parse_protocol, a) == -1) { if (errno != EPIPE) strerr_diefu1sys(111, "read messages from client") ; return 1 ; |
