From 3edda0ebecf5d1be293a4f5f502567dda8229173 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 21 Nov 2025 13:11:02 +0100 Subject: [PATCH] ns: Drop qrtr-ns The qrtr-ns has been superceded by the in-kernel nameserver since multiple years. If anybody wants to do archeology, they can find qrtr-ns with old releases / in the git history. Drop it and remove quite some code. Signed-off-by: Luca Weiss --- .github/workflows/ci.yml | 4 - .gitignore | 1 - Android.bp | 17 - ci/archlinux.sh | 1 - ci/debian.cross-compile.sh | 3 - ci/debian.sh | 4 - ci/fedora.sh | 2 - meson.build | 25 -- meson_options.txt | 16 - qrtr-ns.service.in | 9 - src/hash.c | 37 -- src/hash.h | 12 - src/list.h | 130 ------ src/map.c | 233 ----------- src/map.h | 38 -- src/meson.build | 16 +- src/ns.c | 807 ------------------------------------- src/util.c | 18 - src/util.h | 9 - src/waiter.c | 378 ----------------- src/waiter.h | 103 ----- 21 files changed, 1 insertion(+), 1862 deletions(-) delete mode 100644 meson_options.txt delete mode 100644 qrtr-ns.service.in delete mode 100644 src/hash.c delete mode 100644 src/hash.h delete mode 100644 src/list.h delete mode 100644 src/map.c delete mode 100644 src/map.h delete mode 100644 src/ns.c delete mode 100644 src/util.c delete mode 100644 src/util.h delete mode 100644 src/waiter.c delete mode 100644 src/waiter.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aae0ff0..ed3ba69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,20 +52,17 @@ jobs: #- ubuntu:xenial cross_compile: [""] variant: [""] - nosystemd: [""] include: # Alpine (OpenRC) - container: "alpine:edge" arch: x86-64 family: x86-64 compiler: gcc - nosystemd: true - container: "alpine:latest" arch: x86-64 family: x86-64 compiler: gcc - nosystemd: true # Debian 32-bit builds - container: "debian:testing" @@ -218,7 +215,6 @@ jobs: - name: Meson init with cross compile if: ${{ matrix.variant == 'cross-compile' }} run: | - # installing systemd (for pkg-config) has personality issues with cross-compilation # Generate cross compile file (see https://mesonbuild.com/Cross-compilation.html#cross-compilation) echo "[binaries]" > cross.txt echo "c = '${CROSS_COMPILE}-gcc'" >> cross.txt diff --git a/.gitignore b/.gitignore index 6df6f48..a58048c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ out/ *.so qrtr-cfg qrtr-lookup -qrtr-ns diff --git a/Android.bp b/Android.bp index bfbb7e0..72ef7ef 100644 --- a/Android.bp +++ b/Android.bp @@ -11,22 +11,6 @@ cc_library { local_include_dirs: ["src"], } -cc_binary { - name: "qrtr-ns", - vendor: true, - srcs: [ - "lib/logging.c", - "src/addr.c", - "src/ns.c", - "src/map.c", - "src/hash.c", - "src/waiter.c", - "src/util.c", - ], - cflags: ["-Wno-error"], - local_include_dirs: ["lib"], -} - cc_binary { name: "qrtr-cfg", vendor: true, @@ -45,7 +29,6 @@ cc_binary { srcs: [ "lib/logging.c", "src/lookup.c", - "src/util.c", ], cflags: ["-Wno-error"], local_include_dirs: ["lib"], diff --git a/ci/archlinux.sh b/ci/archlinux.sh index 98eb82d..cf95b26 100755 --- a/ci/archlinux.sh +++ b/ci/archlinux.sh @@ -17,7 +17,6 @@ case $CC in esac pacman -Syu --noconfirm \ - systemd-libs \ pkgconf \ meson \ $PKGS_CC diff --git a/ci/debian.cross-compile.sh b/ci/debian.cross-compile.sh index 5913e5e..be2576e 100755 --- a/ci/debian.cross-compile.sh +++ b/ci/debian.cross-compile.sh @@ -22,7 +22,4 @@ apt install -y --no-install-recommends \ libc6-dev:${ARCH} \ gcc-`dpkg-architecture -a ${ARCH} -q DEB_TARGET_GNU_TYPE` -# Thanks debian -apt install -y --no-install-recommends systemd-dev:${ARCH} -a ${ARCH} || true - echo "Install finished: $0" diff --git a/ci/debian.sh b/ci/debian.sh index 121db85..7360e93 100755 --- a/ci/debian.sh +++ b/ci/debian.sh @@ -30,11 +30,7 @@ esac apt install -y --no-install-recommends \ pkg-config \ meson \ - systemd \ libc6-dev \ $PKGS_CC -# Thanks debian -apt install -y --no-install-recommends systemd-dev || true - echo "Install finished: $0" diff --git a/ci/fedora.sh b/ci/fedora.sh index d8ee851..8ab91f4 100755 --- a/ci/fedora.sh +++ b/ci/fedora.sh @@ -20,8 +20,6 @@ dnf -y install \ meson \ pkg-config \ libudev-devel \ - systemd-devel \ - systemd-libs \ $PKGS_CC echo "Install finished: $0" diff --git a/meson.build b/meson.build index 0afaf84..4ac8234 100644 --- a/meson.build +++ b/meson.build @@ -10,33 +10,8 @@ project('qrtr', ]) prefix = get_option('prefix') -with_qrtr_ns = get_option('qrtr-ns') - -install_systemd_unit = get_option('systemd-service') -systemd = dependency('systemd', required : install_systemd_unit) -if systemd.found() - systemd_system_unit_dir = get_option('systemd-unit-prefix') - if systemd_system_unit_dir == '' - systemd_system_unit_dir = systemd.get_variable( - pkgconfig : 'systemdsystemunitdir', - pkgconfig_define: ['prefix', prefix]) - else - message('Could not resolve systemd dependencies, skipping unit file') - install_systemd_unit = false - endif -endif inc = include_directories('include') subdir('lib') subdir('include') subdir('src') - -if systemd.found() and with_qrtr_ns.enabled() - systemd_unit_conf = configuration_data() - systemd_unit_conf.set('prefix', prefix) - configure_file( - input : 'qrtr-ns.service.in', - output : 'qrtr-ns.service', - configuration : systemd_unit_conf, - install_dir : systemd_system_unit_dir) -endif diff --git a/meson_options.txt b/meson_options.txt deleted file mode 100644 index 5c8fb59..0000000 --- a/meson_options.txt +++ /dev/null @@ -1,16 +0,0 @@ -option('qrtr-ns', - type: 'feature', - value: 'auto', - description: 'Whether or not to build the qrtr-ns binary' -) - -option('systemd-unit-prefix', - type: 'string', - description: 'Directory for systemd system unit files' -) - -option('systemd-service', - type: 'feature', - value: 'auto', - description: 'Whether or not the systemd service should be built' -) diff --git a/qrtr-ns.service.in b/qrtr-ns.service.in deleted file mode 100644 index c830c63..0000000 --- a/qrtr-ns.service.in +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=QIPCRTR Name Service - -[Service] -ExecStart=@prefix@/bin/qrtr-ns -f 1 -Restart=always - -[Install] -WantedBy=multi-user.target diff --git a/src/hash.c b/src/hash.c deleted file mode 100644 index ecfbc0a..0000000 --- a/src/hash.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include "hash.h" - -unsigned int hash_mem(const void *data, unsigned int len) -{ - unsigned int h; - unsigned int i; - - h = len; - - for (i = 0; i < len; ++i) - h = ((h >> 27) ^ (h << 5)) ^ ((const unsigned char *)data)[i]; - - return h; -} - -unsigned int hash_string(const char *value) -{ - return hash_mem(value, strlen(value)); -} - -unsigned int hash_u32(uint32_t value) -{ - return value * 2654435761UL; -} - -unsigned int hash_u64(uint64_t value) -{ - return hash_u32(value & 0xffffffff) ^ hash_u32(value >> 32); -} - -unsigned int hash_pointer(void *value) -{ - if (sizeof(value) == sizeof(uint64_t)) - return hash_u64((long)value); - return hash_u32((long)value); -} diff --git a/src/hash.h b/src/hash.h deleted file mode 100644 index 5b004b5..0000000 --- a/src/hash.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _HASH_H_ -#define _HASH_H_ - -#include - -unsigned int hash_mem(const void *data, unsigned int len); -unsigned int hash_string(const char *value); -unsigned int hash_u32(uint32_t value); -unsigned int hash_u64(uint64_t value); -unsigned int hash_pointer(void *value); - -#endif diff --git a/src/list.h b/src/list.h deleted file mode 100644 index 1d1c8e6..0000000 --- a/src/list.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef _LIST_H_ -#define _LIST_H_ - -#include - -#ifndef offsetof -#define offsetof(type, md) ((size_t)&((type *)0)->md) -#endif - -#ifndef container_of -#define container_of(ptr, type, member) \ - ((type *)((char *)(ptr) - offsetof(type, member))) -#endif - -struct list_item { - struct list_item *next; - struct list_item *prev; -}; - -struct list { - struct list_item *head; - struct list_item *tail; -}; - -#define LIST_INIT(name) { 0, 0 } - -#define LIST(name) \ - struct list name = LIST_INIT(name) - -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -static inline void list_init(struct list *list) -{ - list->head = 0; - list->tail = 0; -} - -static inline void list_append(struct list *list, struct list_item *item) -{ - item->next = 0; - item->prev = list->tail; - if (list->tail != 0) - list->tail->next = item; - else - list->head = item; - list->tail = item; -} - -static inline void list_prepend(struct list *list, struct list_item *item) -{ - item->prev = 0; - item->next = list->head; - if (list->head == 0) - list->tail = item; - list->head = item; -} - -static inline void list_insert(struct list *list, struct list_item *after, struct list_item *item) -{ - if (after == 0) { - list_prepend(list, item); - return; - } - item->prev = after; - item->next = after->next; - after->next = item; - if (item->next) - item->next->prev = item; - if (list->tail == after) - list->tail = item; -} - -static inline void list_remove(struct list *list, struct list_item *item) -{ - if (item->next) - item->next->prev = item->prev; - if (list->head == item) { - list->head = item->next; - if (list->head == 0) - list->tail = 0; - } else { - item->prev->next = item->next; - if (list->tail == item) - list->tail = item->prev; - } - item->prev = item->next = 0; -} - -static inline struct list_item *list_pop(struct list *list) -{ - struct list_item *item; - item = list->head; - if (item == 0) - return 0; - list_remove(list, item); - return item; -} - -static inline struct list_item *list_last(struct list *list) -{ - return list->tail; -} - -static inline struct list_item *list_first(struct list *list) -{ - return list->head; -} - - -static inline struct list_item *list_next(struct list_item *item) -{ - return item->next; -} - -#define list_push list_append - -#define list_for_each(_list, _iter) \ - for (_iter = (_list)->head; (_iter) != 0; _iter = (_iter)->next) - -#define list_for_each_after(_node, _iter) \ - for (_iter = (_node)->next; (_iter) != 0; _iter = (_iter)->next) - -#define list_for_each_safe(_list, _iter, _bkup) \ - for (_iter = (_list)->head; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup)) - -#define list_for_each_safe_after(_node, _iter, _bkup) \ - for (_iter = (_node)->next; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup)) - -#endif diff --git a/src/map.c b/src/map.c deleted file mode 100644 index eed3488..0000000 --- a/src/map.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2008-2009, Courtney Cavin - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include "map.h" - -struct map_entry { - struct map_item *item; -}; - -/* Marker for deleted items */ -static struct map_item deleted; - -void map_destroy(struct map *map) -{ - free(map->data); -} - -void map_clear(struct map *map, void (*release)(struct map_item *)) -{ - int i; - - for (i = 0; i < map->size; ++i){ - if (!map->data[i].item) - continue; - if (map->data[i].item != &deleted) - (* release)(map->data[i].item); - map->data[i].item = NULL; - } - map->count = 0; -} - -int map_create(struct map *map) -{ - map->size = 0; - map->data = 0; - map->count = 0; - return 0; -} - -static int map_hash(struct map *map, unsigned int key) -{ - struct map_entry *e; - int idx, i; - - if (map->count == map->size) - return -1; - - idx = key % map->size; - - for (i = 0; i < map->size; ++i) { - e = &map->data[idx]; - if (!e->item || e->item == &deleted) { - ++map->count; - return idx; - } - if (e->item->key == key) - return idx; - - idx = (idx + 1) % map->size; - } - - return -2; -} - -static int map_rehash(struct map *map); - -int map_reput(struct map *map, unsigned int key, struct map_item *value, - struct map_item **old) -{ - int rc; - - while ((rc = map_hash(map, key)) < 0) { - if ((rc = map_rehash(map)) < 0) - return rc; - } - - if (old) { - if (map->data[rc].item == &deleted) - *old = NULL; - else - *old = map->data[rc].item; - } - map->data[rc].item = value; - if (value) - map->data[rc].item->key = key; - - return 0; -} - -int map_put(struct map *map, unsigned int key, struct map_item *value) -{ - return map_reput(map, key, value, NULL); -} - -static int map_rehash(struct map *map) -{ - struct map_entry *oldt, *newt; - int o_size, i; - int rc; - - newt = calloc(sizeof(struct map_entry), map->size + 256); - if (!newt) - return -1; - - oldt = map->data; - map->data = newt; - - o_size = map->size; - map->size += 256; - map->count = 0; - - for (i = 0; i < o_size; ++i){ - if (!oldt[i].item || oldt[i].item == &deleted) - continue; - rc = map_put(map, oldt[i].item->key, oldt[i].item); - if (rc < 0) - return rc; - } - - free(oldt); - - return 0; -} - -static struct map_entry *map_find(const struct map *map, unsigned int key) -{ - struct map_entry *e; - int idx, i; - - if (map->size == 0) - return NULL; - - idx = key % map->size; - - for (i = 0; i < map->size; ++i) { - e = &map->data[idx]; - idx = (idx + 1) % map->size; - - if (!e->item) - break; - if (e->item == &deleted) - continue; - if (e->item->key == key) - return e; - } - return NULL; -} - -int map_contains(const struct map *map, unsigned int key) -{ - return (map_find(map, key) == NULL) ? 0 : 1; -} - -struct map_item *map_get(const struct map *map, unsigned int key) -{ - struct map_entry *e; - - e = map_find(map, key); - if (e == NULL) - return NULL; - return e->item; -} - -int map_remove(struct map *map, unsigned int key) -{ - struct map_entry *e; - - e = map_find(map, key); - if (e) { - e->item = &deleted; - --map->count; - } - return !e; -} - -unsigned int map_length(struct map *map) -{ - return map ? map->count : 0; -} - -static struct map_entry *map_iter_from(const struct map *map, unsigned int start) -{ - unsigned int i = start; - - for (; i < map->size; ++i) { - if (map->data[i].item && map->data[i].item != &deleted) - return &map->data[i]; - } - return NULL; -} - -struct map_entry *map_iter_next(const struct map *map, struct map_entry *iter) -{ - if (iter == NULL) - return NULL; - - return map_iter_from(map, (iter - map->data) + 1); -} - -struct map_entry *map_iter_first(const struct map *map) -{ - return map_iter_from(map, 0); -} - - -struct map_item *map_iter_item(struct map_entry *iter) -{ - return iter->item; -} diff --git a/src/map.h b/src/map.h deleted file mode 100644 index de68e19..0000000 --- a/src/map.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _MAP_H_ -#define _MAP_H_ - -struct map_item { - unsigned int key; -}; - -struct map_entry; - -struct map { - unsigned int size; - unsigned int count; - struct map_entry *data; -}; - -int map_create(struct map *map); -void map_destroy(struct map *map); -void map_clear(struct map *map, void (*release)(struct map_item *)); - -int map_put(struct map *map, unsigned int key, struct map_item *v); -int map_reput(struct map *map, unsigned int key, struct map_item *v, - struct map_item **old); -int map_contains(const struct map *map, unsigned int key); -struct map_item *map_get(const struct map *map, unsigned int key); -int map_remove(struct map *map, unsigned int key); -unsigned int map_length(struct map *map); - -struct map_entry *map_iter_first(const struct map *map); -struct map_entry *map_iter_next(const struct map *map, struct map_entry *iter); -struct map_item *map_iter_item(struct map_entry *iter); - -#define map_for_each(map, iter) \ - for (iter = map_iter_first(map); iter; iter = map_iter_next(map, iter)) - -#define map_iter_data(iter, type, member) \ - container_of(map_iter_item(iter), type, member) - -#endif diff --git a/src/meson.build b/src/meson.build index ab02c31..a9bd342 100644 --- a/src/meson.build +++ b/src/meson.build @@ -8,22 +8,8 @@ executable('qrtr-cfg', include_directories : inc, install : true) -if with_qrtr_ns.enabled() - ns_srcs = ['addr.c', - 'hash.c', - 'map.c', - 'ns.c', - 'util.c', - 'waiter.c'] - executable('qrtr-ns', - ns_srcs, - link_with : libqrtr, - include_directories : inc, - install : true) -endif - executable('qrtr-lookup', 'lookup.c', link_with : libqrtr, include_directories : inc, - install : true) \ No newline at end of file + install : true) diff --git a/src/ns.c b/src/ns.c deleted file mode 100644 index 1e847a8..0000000 --- a/src/ns.c +++ /dev/null @@ -1,807 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "addr.h" -#include "hash.h" -#include "list.h" -#include "map.h" -#include "ns.h" -#include "util.h" -#include "waiter.h" - -#include "logging.h" - -static const char *ctrl_pkt_strings[] = { - [QRTR_TYPE_HELLO] = "hello", - [QRTR_TYPE_BYE] = "bye", - [QRTR_TYPE_NEW_SERVER] = "new-server", - [QRTR_TYPE_DEL_SERVER] = "del-server", - [QRTR_TYPE_DEL_CLIENT] = "del-client", - [QRTR_TYPE_RESUME_TX] = "resume-tx", - [QRTR_TYPE_EXIT] = "exit", - [QRTR_TYPE_PING] = "ping", - [QRTR_TYPE_NEW_LOOKUP] = "new-lookup", - [QRTR_TYPE_DEL_LOOKUP] = "del-lookup", -}; - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) - -struct context { - int sock; - - int local_node; - - struct sockaddr_qrtr bcast_sq; - - struct list lookups; -}; - -struct server_filter { - unsigned int service; - unsigned int instance; - unsigned int ifilter; -}; - -struct lookup { - unsigned int service; - unsigned int instance; - - struct sockaddr_qrtr sq; - struct list_item li; -}; - -struct server { - unsigned int service; - unsigned int instance; - - unsigned int node; - unsigned int port; - struct map_item mi; - struct list_item qli; -}; - -struct node { - unsigned int id; - - struct map_item mi; - struct map services; -}; - -static struct map nodes; - -static void server_mi_free(struct map_item *mi); - -static struct node *node_get(unsigned int node_id) -{ - struct map_item *mi; - struct node *node; - int rc; - - mi = map_get(&nodes, hash_u32(node_id)); - if (mi) - return container_of(mi, struct node, mi); - - node = calloc(1, sizeof(*node)); - if (!node) - return NULL; - - node->id = node_id; - - rc = map_create(&node->services); - if (rc) - LOGE_AND_EXIT("unable to create map"); - - rc = map_put(&nodes, hash_u32(node_id), &node->mi); - if (rc) { - map_destroy(&node->services); - free(node); - return NULL; - } - - return node; -} - -static int server_match(const struct server *srv, const struct server_filter *f) -{ - unsigned int ifilter = f->ifilter; - - if (f->service != 0 && srv->service != f->service) - return 0; - if (!ifilter && f->instance) - ifilter = ~0; - return (srv->instance & ifilter) == f->instance; -} - -static int server_query(const struct server_filter *f, struct list *list) -{ - struct map_entry *node_me; - struct map_entry *me; - struct node *node; - int count = 0; - - list_init(list); - map_for_each(&nodes, node_me) { - node = map_iter_data(node_me, struct node, mi); - - map_for_each(&node->services, me) { - struct server *srv; - - srv = map_iter_data(me, struct server, mi); - if (!server_match(srv, f)) - continue; - - list_append(list, &srv->qli); - ++count; - } - } - - return count; -} - -static int service_announce_new(struct context *ctx, - struct sockaddr_qrtr *dest, - struct server *srv) -{ - struct qrtr_ctrl_pkt cmsg; - int rc; - - LOGD("advertising new server [%u:%x]@[%u:%u]\n", - srv->service, srv->instance, srv->node, srv->port); - - cmsg.cmd = cpu_to_le32(QRTR_TYPE_NEW_SERVER); - cmsg.server.service = cpu_to_le32(srv->service); - cmsg.server.instance = cpu_to_le32(srv->instance); - cmsg.server.node = cpu_to_le32(srv->node); - cmsg.server.port = cpu_to_le32(srv->port); - - rc = sendto(ctx->sock, &cmsg, sizeof(cmsg), 0, - (struct sockaddr *)dest, sizeof(*dest)); - if (rc < 0) - PLOGW("sendto()"); - - return rc; -} - -static int service_announce_del(struct context *ctx, - struct sockaddr_qrtr *dest, - struct server *srv) -{ - struct qrtr_ctrl_pkt cmsg; - int rc; - - LOGD("advertising removal of server [%u:%x]@[%u:%u]\n", - srv->service, srv->instance, srv->node, srv->port); - - cmsg.cmd = cpu_to_le32(QRTR_TYPE_DEL_SERVER); - cmsg.server.service = cpu_to_le32(srv->service); - cmsg.server.instance = cpu_to_le32(srv->instance); - cmsg.server.node = cpu_to_le32(srv->node); - cmsg.server.port = cpu_to_le32(srv->port); - - rc = sendto(ctx->sock, &cmsg, sizeof(cmsg), 0, - (struct sockaddr *)dest, sizeof(*dest)); - if (rc < 0) - PLOGW("sendto()"); - - return rc; -} - -static int lookup_notify(struct context *ctx, struct sockaddr_qrtr *to, - struct server *srv, bool new) -{ - struct qrtr_ctrl_pkt pkt = {}; - int rc; - - pkt.cmd = new ? QRTR_TYPE_NEW_SERVER : QRTR_TYPE_DEL_SERVER; - if (srv) { - pkt.server.service = cpu_to_le32(srv->service); - pkt.server.instance = cpu_to_le32(srv->instance); - pkt.server.node = cpu_to_le32(srv->node); - pkt.server.port = cpu_to_le32(srv->port); - } - - rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0, - (struct sockaddr *)to, sizeof(*to)); - if (rc < 0) - PLOGW("send lookup result failed"); - return rc; -} - -static int annouce_servers(struct context *ctx, struct sockaddr_qrtr *sq) -{ - struct map_entry *me; - struct server *srv; - struct node *node; - int rc; - - node = node_get(ctx->local_node); - if (!node) - return 0; - - map_for_each(&node->services, me) { - srv = map_iter_data(me, struct server, mi); - - rc = service_announce_new(ctx, sq, srv); - if (rc < 0) - return rc; - } - - return 0; -} - -static struct server *server_add(unsigned int service, unsigned int instance, - unsigned int node_id, unsigned int port) -{ - struct map_item *mi; - struct server *srv; - struct node *node; - int rc; - - if (!service || !port) - return NULL; - - srv = calloc(1, sizeof(*srv)); - if (srv == NULL) - return NULL; - - srv->service = service; - srv->instance = instance; - srv->node = node_id; - srv->port = port; - - node = node_get(node_id); - if (!node) - goto err; - - rc = map_reput(&node->services, hash_u32(port), &srv->mi, &mi); - if (rc) - goto err; - - LOGD("add server [%u:%x]@[%u:%u]\n", srv->service, srv->instance, - srv->node, srv->port); - - if (mi) { /* we replaced someone */ - struct server *old = container_of(mi, struct server, mi); - free(old); - } - - return srv; - -err: - free(srv); - return NULL; -} - -static int server_del(struct context *ctx, struct node *node, unsigned int port) -{ - struct lookup *lookup; - struct list_item *li; - struct map_item *mi; - struct server *srv; - - mi = map_get(&node->services, hash_u32(port)); - if (!mi) - return -ENOENT; - - srv = container_of(mi, struct server, mi); - map_remove(&node->services, srv->mi.key); - - /* Broadcast the removal of local services */ - if (srv->node == ctx->local_node) - service_announce_del(ctx, &ctx->bcast_sq, srv); - - /* Announce the service's disappearance to observers */ - list_for_each(&ctx->lookups, li) { - lookup = container_of(li, struct lookup, li); - if (lookup->service && lookup->service != srv->service) - continue; - if (lookup->instance && lookup->instance != srv->instance) - continue; - - lookup_notify(ctx, &lookup->sq, srv, false); - } - - free(srv); - - return 0; -} - -static int ctrl_cmd_hello(struct context *ctx, struct sockaddr_qrtr *sq, - const void *buf, size_t len) -{ - int rc; - - rc = sendto(ctx->sock, buf, len, 0, (void *)sq, sizeof(*sq)); - if (rc > 0) - rc = annouce_servers(ctx, sq); - - return rc; -} - -static int ctrl_cmd_bye(struct context *ctx, struct sockaddr_qrtr *from) -{ - struct qrtr_ctrl_pkt pkt; - struct sockaddr_qrtr sq; - struct node *local_node; - struct map_entry *me; - struct server *srv; - struct node *node; - int rc; - - node = node_get(from->sq_node); - if (!node) - return 0; - - map_for_each(&node->services, me) { - srv = map_iter_data(me, struct server, mi); - - server_del(ctx, node, srv->port); - } - - /* Advertise the removal of this client to all local services */ - local_node = node_get(ctx->local_node); - if (!local_node) - return 0; - - memset(&pkt, 0, sizeof(pkt)); - pkt.cmd = QRTR_TYPE_BYE; - pkt.client.node = from->sq_node; - - map_for_each(&local_node->services, me) { - srv = map_iter_data(me, struct server, mi); - - sq.sq_family = AF_QIPCRTR; - sq.sq_node = srv->node; - sq.sq_port = srv->port; - - rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0, - (struct sockaddr *)&sq, sizeof(sq)); - if (rc < 0) - PLOGW("bye propagation failed"); - } - - return 0; -} - -static int ctrl_cmd_del_client(struct context *ctx, struct sockaddr_qrtr *from, - unsigned node_id, unsigned port) -{ - struct qrtr_ctrl_pkt pkt; - struct sockaddr_qrtr sq; - struct node *local_node; - struct list_item *tmp; - struct lookup *lookup; - struct list_item *li; - struct map_entry *me; - struct server *srv; - struct node *node; - int rc; - - /* Don't accept spoofed messages */ - if (from->sq_node != node_id) - return -EINVAL; - - /* Local DEL_CLIENT messages comes from the port being closed */ - if (from->sq_node == ctx->local_node && from->sq_port != port) - return -EINVAL; - - /* Remove any lookups by this client */ - list_for_each_safe(&ctx->lookups, li, tmp) { - lookup = container_of(li, struct lookup, li); - if (lookup->sq.sq_node != node_id) - continue; - if (lookup->sq.sq_port != port) - continue; - - list_remove(&ctx->lookups, &lookup->li); - free(lookup); - } - - /* Remove the server belonging to this port*/ - node = node_get(node_id); - if (node) - server_del(ctx, node, port); - - /* Advertise the removal of this client to all local services */ - local_node = node_get(ctx->local_node); - if (!local_node) - return 0; - - pkt.cmd = QRTR_TYPE_DEL_CLIENT; - pkt.client.node = node_id; - pkt.client.port = port; - - map_for_each(&local_node->services, me) { - srv = map_iter_data(me, struct server, mi); - - sq.sq_family = AF_QIPCRTR; - sq.sq_node = srv->node; - sq.sq_port = srv->port; - - rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0, - (struct sockaddr *)&sq, sizeof(sq)); - if (rc < 0) - PLOGW("del_client propagation failed"); - } - - return 0; -} - -static int ctrl_cmd_new_server(struct context *ctx, struct sockaddr_qrtr *from, - unsigned int service, unsigned int instance, - unsigned int node_id, unsigned int port) -{ - struct lookup *lookup; - struct list_item *li; - struct server *srv; - int rc = 0; - - /* Ignore specified node and port for local servers*/ - if (from->sq_node == ctx->local_node) { - node_id = from->sq_node; - port = from->sq_port; - } - - /* Don't accept spoofed messages */ - if (from->sq_node != node_id) - return -EINVAL; - - srv = server_add(service, instance, node_id, port); - if (!srv) - return -EINVAL; - - if (srv->node == ctx->local_node) - rc = service_announce_new(ctx, &ctx->bcast_sq, srv); - - list_for_each(&ctx->lookups, li) { - lookup = container_of(li, struct lookup, li); - if (lookup->service && lookup->service != service) - continue; - if (lookup->instance && lookup->instance != instance) - continue; - - lookup_notify(ctx, &lookup->sq, srv, true); - } - - return rc; -} - -static int ctrl_cmd_del_server(struct context *ctx, struct sockaddr_qrtr *from, - unsigned int service, unsigned int instance, - unsigned int node_id, unsigned int port) -{ - struct node *node; - - /* Ignore specified node and port for local servers*/ - if (from->sq_node == ctx->local_node) { - node_id = from->sq_node; - port = from->sq_port; - } - - /* Don't accept spoofed messages */ - if (from->sq_node != node_id) - return -EINVAL; - - /* Local servers may only unregister themselves */ - if (from->sq_node == ctx->local_node && from->sq_port != port) - return -EINVAL; - - node = node_get(node_id); - if (!node) - return -ENOENT; - - return server_del(ctx, node, port); -} - -static int ctrl_cmd_new_lookup(struct context *ctx, struct sockaddr_qrtr *from, - unsigned int service, unsigned int instance) -{ - struct server_filter filter; - struct list reply_list; - struct lookup *lookup; - struct list_item *li; - struct server *srv; - - /* Accept only local observers */ - if (from->sq_node != ctx->local_node) - return -EINVAL; - - lookup = calloc(1, sizeof(*lookup)); - if (!lookup) - return -EINVAL; - - lookup->sq = *from; - lookup->service = service; - lookup->instance = instance; - list_append(&ctx->lookups, &lookup->li); - - memset(&filter, 0, sizeof(filter)); - filter.service = service; - filter.instance = instance; - - server_query(&filter, &reply_list); - list_for_each(&reply_list, li) { - srv = container_of(li, struct server, qli); - - lookup_notify(ctx, from, srv, true); - } - - lookup_notify(ctx, from, NULL, true); - - return 0; -} - -static int ctrl_cmd_del_lookup(struct context *ctx, struct sockaddr_qrtr *from, - unsigned int service, unsigned int instance) -{ - struct lookup *lookup; - struct list_item *tmp; - struct list_item *li; - - list_for_each_safe(&ctx->lookups, li, tmp) { - lookup = container_of(li, struct lookup, li); - if (lookup->sq.sq_node != from->sq_node) - continue; - if (lookup->sq.sq_port != from->sq_port) - continue; - if (lookup->service != service) - continue; - if (lookup->instance && lookup->instance != instance) - continue; - - list_remove(&ctx->lookups, &lookup->li); - free(lookup); - } - - return 0; -} - -static void ctrl_port_fn(void *vcontext, struct waiter_ticket *tkt) -{ - struct context *ctx = vcontext; - struct sockaddr_qrtr sq; - int sock = ctx->sock; - struct qrtr_ctrl_pkt *msg; - unsigned int cmd; - char buf[4096]; - socklen_t sl; - ssize_t len; - int rc; - - sl = sizeof(sq); - len = recvfrom(sock, buf, sizeof(buf), 0, (void *)&sq, &sl); - if (len <= 0) { - PLOGW("recvfrom()"); - close(sock); - ctx->sock = -1; - goto out; - } - msg = (void *)buf; - - if (len < 4) { - LOGW("short packet from %u:%u", sq.sq_node, sq.sq_port); - goto out; - } - - cmd = le32_to_cpu(msg->cmd); - if (cmd < ARRAY_SIZE(ctrl_pkt_strings) && ctrl_pkt_strings[cmd]) - LOGD("%s from %u:%u\n", ctrl_pkt_strings[cmd], sq.sq_node, sq.sq_port); - else - LOGD("UNK (%08x) from %u:%u\n", cmd, sq.sq_node, sq.sq_port); - - rc = 0; - switch (cmd) { - case QRTR_TYPE_HELLO: - rc = ctrl_cmd_hello(ctx, &sq, buf, len); - break; - case QRTR_TYPE_BYE: - rc = ctrl_cmd_bye(ctx, &sq); - break; - case QRTR_TYPE_DEL_CLIENT: - rc = ctrl_cmd_del_client(ctx, &sq, - le32_to_cpu(msg->client.node), - le32_to_cpu(msg->client.port)); - break; - case QRTR_TYPE_NEW_SERVER: - rc = ctrl_cmd_new_server(ctx, &sq, - le32_to_cpu(msg->server.service), - le32_to_cpu(msg->server.instance), - le32_to_cpu(msg->server.node), - le32_to_cpu(msg->server.port)); - break; - case QRTR_TYPE_DEL_SERVER: - rc = ctrl_cmd_del_server(ctx, &sq, - le32_to_cpu(msg->server.service), - le32_to_cpu(msg->server.instance), - le32_to_cpu(msg->server.node), - le32_to_cpu(msg->server.port)); - break; - case QRTR_TYPE_EXIT: - case QRTR_TYPE_PING: - case QRTR_TYPE_RESUME_TX: - break; - case QRTR_TYPE_NEW_LOOKUP: - rc = ctrl_cmd_new_lookup(ctx, &sq, - le32_to_cpu(msg->server.service), - le32_to_cpu(msg->server.instance)); - break; - case QRTR_TYPE_DEL_LOOKUP: - rc = ctrl_cmd_del_lookup(ctx, &sq, - le32_to_cpu(msg->server.service), - le32_to_cpu(msg->server.instance)); - break; - } - - if (rc < 0) - LOGW("failed while handling packet from %u:%u", - sq.sq_node, sq.sq_port); -out: - waiter_ticket_clear(tkt); -} - -static int say_hello(struct context *ctx) -{ - struct qrtr_ctrl_pkt pkt; - int rc; - - memset(&pkt, 0, sizeof(pkt)); - pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO); - - rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0, - (struct sockaddr *)&ctx->bcast_sq, sizeof(ctx->bcast_sq)); - if (rc < 0) - return rc; - - return 0; -} - -static void server_mi_free(struct map_item *mi) -{ - free(container_of(mi, struct server, mi)); -} - -static void node_mi_free(struct map_item *mi) -{ - struct node *node = container_of(mi, struct node, mi); - - map_clear(&node->services, server_mi_free); - map_destroy(&node->services); - - free(node); -} - -static void go_dormant(int sock) -{ - close(sock); - - for (;;) - sleep(UINT_MAX); -} - -static void usage(const char *progname) -{ - fprintf(stderr, "%s [-f] [-s] []\n", progname); - exit(1); -} - -int main(int argc, char **argv) -{ - struct waiter_ticket *tkt; - struct sockaddr_qrtr sq; - struct context ctx; - unsigned long addr = (unsigned long)-1; - struct waiter *w; - socklen_t sl = sizeof(sq); - bool foreground = false; - bool use_syslog = false; - bool verbose_log = false; - char *ep; - int opt; - int rc; - const char *progname = basename(argv[0]); - - while ((opt = getopt(argc, argv, "fsv")) != -1) { - switch (opt) { - case 'f': - foreground = true; - break; - case 's': - use_syslog = true; - break; - case 'v': - verbose_log = true; - break; - default: - usage(progname); - } - } - - qlog_setup(progname, use_syslog); - if (verbose_log) - qlog_set_min_priority(LOG_DEBUG); - - if (optind < argc) { - addr = strtoul(argv[optind], &ep, 10); - if (argv[1][0] == '\0' || *ep != '\0' || addr >= UINT_MAX) - usage(progname); - - qrtr_set_address(addr); - optind++; - } - - if (optind != argc) - usage(progname); - - w = waiter_create(); - if (w == NULL) - LOGE_AND_EXIT("unable to create waiter"); - - list_init(&ctx.lookups); - - rc = map_create(&nodes); - if (rc) - LOGE_AND_EXIT("unable to create node map"); - - ctx.sock = socket(AF_QIPCRTR, SOCK_DGRAM, 0); - if (ctx.sock < 0) - PLOGE_AND_EXIT("unable to create control socket"); - - rc = getsockname(ctx.sock, (void*)&sq, &sl); - if (rc < 0) - PLOGE_AND_EXIT("getsockname()"); - sq.sq_port = QRTR_PORT_CTRL; - ctx.local_node = sq.sq_node; - - rc = bind(ctx.sock, (void *)&sq, sizeof(sq)); - if (rc < 0) { - if (errno == EADDRINUSE) { - PLOGE("nameserver already running, going dormant"); - go_dormant(ctx.sock); - } - - PLOGE_AND_EXIT("bind control socket"); - } - - ctx.bcast_sq.sq_family = AF_QIPCRTR; - ctx.bcast_sq.sq_node = QRTR_NODE_BCAST; - ctx.bcast_sq.sq_port = QRTR_PORT_CTRL; - - rc = say_hello(&ctx); - if (rc) - PLOGE_AND_EXIT("unable to say hello"); - - /* If we're going to background, fork and exit parent */ - if (!foreground && fork() != 0) { - close(ctx.sock); - exit(0); - } - - tkt = waiter_add_fd(w, ctx.sock); - waiter_ticket_callback(tkt, ctrl_port_fn, &ctx); - - while (ctx.sock >= 0) - waiter_wait(w); - - puts("exiting cleanly"); - - waiter_destroy(w); - - map_clear(&nodes, node_mi_free); - map_destroy(&nodes); - - return 0; -} diff --git a/src/util.c b/src/util.c deleted file mode 100644 index 48d9d27..0000000 --- a/src/util.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include -#include -#include - -#include "util.h" - -uint64_t time_ms(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (uint64_t)tv.tv_sec*1000 + tv.tv_usec/1000; -} - -void util_sleep(int ms) -{ - usleep(ms * 1000); -} diff --git a/src/util.h b/src/util.h deleted file mode 100644 index 3f371cd..0000000 --- a/src/util.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __UTIL_H_ -#define __UTIL_H_ - -#include - -uint64_t time_ms(void); -void util_sleep(int ms); - -#endif diff --git a/src/waiter.c b/src/waiter.c deleted file mode 100644 index f21896f..0000000 --- a/src/waiter.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2013-2014, Sony Mobile Communications Inc. - * Copyright (c) 2014, Courtney Cavin - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the organization nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include "list.h" -#include "waiter.h" -#include "util.h" - -struct pollset { - int nfds; - int cause; -}; - -static struct pollset *pollset_create(int count) -{ - struct pollset *ps; - - ps = calloc(1, sizeof(*ps) + sizeof(struct pollfd) * count); - if (ps == NULL) - return NULL; - - return ps; -} - -static void pollset_destroy(struct pollset *ps) -{ - free(ps); -} - -static void pollset_reset(struct pollset *ps) -{ - ps->nfds = 0; -} - -static void pollset_add_fd(struct pollset *ps, int fd) -{ - struct pollfd *pfd = (struct pollfd *)(ps + 1); - pfd[ps->nfds].fd = fd; - pfd[ps->nfds].events = POLLERR | POLLIN; - ps->nfds++; -} - -static int pollset_wait(struct pollset *ps, int ms) -{ - struct pollfd *pfd = (struct pollfd *)(ps + 1); - int rc; - int i; - - rc = poll(pfd, ps->nfds, ms); - if (rc <= 0) - return rc; - - ps->cause = -1; - for (i = 0; i < ps->nfds; ++i) { - if (pfd[i].revents & (POLLERR | POLLIN)) { - ps->cause = i; - break; - } - } - return rc; - -} - -static int pollset_cause_fd(struct pollset *ps, int fd) -{ - struct pollfd *pfd = (struct pollfd *)(ps + 1); - return (ps->cause >= 0 && pfd[ps->cause].fd == fd); -} - -enum waiter_type { - WATCH_TYPE_NULL, - WATCH_TYPE_FD, - WATCH_TYPE_TIMEOUT, -}; - -struct waiter_ticket { - enum waiter_type type; - union { - int filedes; - unsigned int event; - unsigned int interval; - }; - struct { - void (* fn)(void *data, struct waiter_ticket *); - void *data; - } callback; - - uint64_t start; - int updated; - struct waiter *waiter; - struct list_item list_item; -}; - -struct waiter { - struct list tickets; - struct pollset *pollset; - int count; -}; - -struct waiter *waiter_create(void) -{ - struct waiter *w; - - w = calloc(1, sizeof(*w)); - if (w == NULL) - return NULL; - - list_init(&w->tickets); - return w; -} - -void waiter_destroy(struct waiter *w) -{ - struct waiter_ticket *ticket; - struct list_item *safe; - struct list_item *node; - - list_for_each_safe(&w->tickets, node, safe) { - ticket = list_entry(node, struct waiter_ticket, list_item); - free(ticket); - } - - if (w->pollset) - pollset_destroy(w->pollset); - free(w); -} - -void waiter_synchronize(struct waiter *w) -{ - struct waiter_ticket *oticket; - struct waiter_ticket *ticket; - struct list_item *node; - - list_for_each(&w->tickets, node) { - struct list_item *onode; - ticket = list_entry(node, struct waiter_ticket, list_item); - - if (ticket->type != WATCH_TYPE_TIMEOUT) - continue; - - list_for_each_after(node, onode) { - oticket = list_entry(onode, struct waiter_ticket, list_item); - if (oticket->type != WATCH_TYPE_TIMEOUT) - continue; - - if (oticket->interval == ticket->interval) { - oticket->start = ticket->start; - break; - } - } - } -} - -void waiter_wait(struct waiter *w) -{ - struct pollset *ps = w->pollset; - struct waiter_ticket *ticket; - struct list_item *node; - uint64_t term_time; - uint64_t now; - int rc; - - pollset_reset(ps); - - term_time = (uint64_t)-1; - list_for_each(&w->tickets, node) { - ticket = list_entry(node, struct waiter_ticket, list_item); - switch (ticket->type) { - case WATCH_TYPE_TIMEOUT: - if (ticket->start + ticket->interval < term_time) - term_time = ticket->start + ticket->interval; - break; - case WATCH_TYPE_FD: - pollset_add_fd(ps, ticket->filedes); - break; - case WATCH_TYPE_NULL: - break; - } - } - - if (term_time == (uint64_t)-1) { /* wait forever */ - rc = pollset_wait(ps, -1); - } else { - now = time_ms(); - if (now >= term_time) { /* already past timeout, skip poll */ - rc = 0; - } else { - uint64_t delta; - - delta = term_time - now; - if (delta > ((1u << 31) - 1)) - delta = ((1u << 31) - 1); - rc = pollset_wait(ps, (int)delta); - } - } - - if (rc < 0) - return; - - now = time_ms(); - list_for_each(&w->tickets, node) { - int fresh = 0; - - ticket = list_entry(node, struct waiter_ticket, list_item); - switch (ticket->type) { - case WATCH_TYPE_TIMEOUT: - if (now >= ticket->start + ticket->interval) { - ticket->start = now; - fresh = !ticket->updated; - } - break; - case WATCH_TYPE_FD: - if (rc == 0) /* timed-out */ - break; - if (pollset_cause_fd(ps, ticket->filedes)) - fresh = !ticket->updated; - break; - case WATCH_TYPE_NULL: - break; - } - if (fresh) { - ticket->updated = 1; - if (ticket->callback.fn) - (* ticket->callback.fn)( - ticket->callback.data, - ticket - ); - } - } -} - -int waiter_wait_timeout(struct waiter *w, unsigned int ms) -{ - struct waiter_ticket ticket; - int rc; - - memset(&ticket, 0, sizeof(ticket)); - waiter_ticket_set_timeout(&ticket, ms); - list_append(&w->tickets, &ticket.list_item); - w->count++; - - waiter_wait(w); - rc = waiter_ticket_check(&ticket); - - list_remove(&w->tickets, &ticket.list_item); - w->count--; - - return -!rc; -} - -void waiter_ticket_set_null(struct waiter_ticket *ticket) -{ - ticket->type = WATCH_TYPE_NULL; -} - -void waiter_ticket_set_fd(struct waiter_ticket *ticket, int fd) -{ - ticket->type = WATCH_TYPE_FD; - ticket->filedes = fd; -} - -void waiter_ticket_set_timeout(struct waiter_ticket *ticket, unsigned int ms) -{ - ticket->type = WATCH_TYPE_TIMEOUT; - ticket->interval = ms; - ticket->start = time_ms(); -} - -struct waiter_ticket *waiter_add_null(struct waiter *w) -{ - struct waiter_ticket *ticket; - - ticket = calloc(1, sizeof(*ticket)); - if (ticket == NULL) - return NULL; - ticket->waiter = w; - - list_append(&w->tickets, &ticket->list_item); - if ((w->count % 32) == 0) { - if (w->pollset) - pollset_destroy(w->pollset); - w->pollset = pollset_create(w->count + 33); - if (w->pollset == NULL) - return NULL; - } - w->count++; - - waiter_ticket_set_null(ticket); - - return ticket; -} - -struct waiter_ticket *waiter_add_fd(struct waiter *w, int fd) -{ - struct waiter_ticket *ticket; - - ticket = waiter_add_null(w); - if (ticket == NULL) - return NULL; - - waiter_ticket_set_fd(ticket, fd); - - return ticket; -} - -struct waiter_ticket *waiter_add_timeout(struct waiter *w, unsigned int ms) -{ - struct waiter_ticket *ticket; - - ticket = waiter_add_null(w); - if (ticket == NULL) - return NULL; - - waiter_ticket_set_timeout(ticket, ms); - - return ticket; -} - -void waiter_ticket_delete(struct waiter_ticket *ticket) -{ - struct waiter *w = ticket->waiter; - list_remove(&w->tickets, &ticket->list_item); - w->count--; - free(ticket); -} - -void waiter_ticket_callback(struct waiter_ticket *ticket, waiter_ticket_cb_t cb_fn, void *data) -{ - ticket->callback.fn = cb_fn; - ticket->callback.data = data; -} - -int waiter_ticket_check(const struct waiter_ticket *ticket) -{ - return -(ticket->updated == 0); -} - -int waiter_ticket_clear(struct waiter_ticket *ticket) -{ - int ret; - - ret = waiter_ticket_check(ticket); - ticket->updated = 0; - - return ret; -} diff --git a/src/waiter.h b/src/waiter.h deleted file mode 100644 index e311453..0000000 --- a/src/waiter.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _WAITER_H_ -#define _WAITER_H_ - -/** Waiter type. */ -struct waiter; - -/** Create a new waiter. - * @return Newly created waiter on success, NULL on failure. - */ -struct waiter *waiter_create(void); - -/** Destroy existing waiter. - * @param w waiter to destroy. - */ -void waiter_destroy(struct waiter *w); - -/** Wait for next ticket. - * @param w waiter. - */ -void waiter_wait(struct waiter *w); - -/** Wait for next ticket or timeout. - * @param w waiter. - * @param ms timeout in milliseconds. - * @return 0 on ticket; !0 on timeout. - */ -int waiter_wait_timeout(struct waiter *w, unsigned int ms); - -/** Synchronize timer-based tickets. - * @param w waiter. - */ -void waiter_synchronize(struct waiter *w); - -/** Waiter ticket type. */ -struct waiter_ticket; - -/** Add a null wait ticket to pool. - * @param w waiter - * @return wait ticket on success; NULL on failure. - */ -struct waiter_ticket *waiter_add_null(struct waiter *w); - -/** Add a file descriptor to the pool. - * @param w waiter. - * @param fd file descriptor. - * @return wait ticket on success; NULL on failure. - */ -struct waiter_ticket *waiter_add_fd(struct waiter *w, int fd); - -/** Add a timeout to the pool. - * @param w waiter. - * @param ms duration of timeout in milliseconds. - * @return wait ticket on success; NULL on failure. - */ -struct waiter_ticket *waiter_add_timeout(struct waiter *w, unsigned int ms); - -/** Set ticket type to null. - * @param tkt wait ticket. - */ -void waiter_ticket_set_null(struct waiter_ticket *tkt); - -/** Set ticket type to file descriptor. - * @param tkt wait ticket. - * @param fd file descriptor. - */ -void waiter_ticket_set_fd(struct waiter_ticket *tkt, int fd); - -/** Set ticket type to timeout. - * @param tkt wait ticket. - * @param ms timeout in milliseconds. - */ -void waiter_ticket_set_timeout(struct waiter_ticket *tkt, unsigned int ms); - -/** Destroy ticket. - * @param tkt wait ticket. - */ -void waiter_ticket_delete(struct waiter_ticket *tkt); - -/** Check to see if ticket has triggered. - * @param tkt wait ticket. - * @return 0 if triggered, !0 otherwise. - */ -int waiter_ticket_check(const struct waiter_ticket *tkt); - - -/** Clear ticket trigger status. - * @param tkt wait ticket. - * @return 0 if triggered, !0 otherwise. - */ -int waiter_ticket_clear(struct waiter_ticket *tkt); - -/** Wait ticket callback function type. */ -typedef void (* waiter_ticket_cb_t)(void *, struct waiter_ticket *); - -/** Register callback function for ticket trigger. - * @param tkt wait ticket. - * @param cb_fn callback function. - * @param data private data to pass to callback function. - */ -void waiter_ticket_callback(struct waiter_ticket *tkt, - waiter_ticket_cb_t cb_fn, void *data); - -#endif