From: John Crispin Date: Wed, 22 Jan 2014 13:53:11 +0000 (+0000) Subject: add auto (re)connect logic to libubus X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fubus.git;a=commitdiff_plain;h=29d7092252a10c11ac137e38c871e301e26a8c11;hp=8ea96670367e5dd23988b51ee4f0f790393effaf;ds=sidebyside add auto (re)connect logic to libubus Signed-off-by: John Crispin --- diff --git a/libubus.c b/libubus.c index c6e956a..e435200 100644 --- a/libubus.c +++ b/libubus.c @@ -267,14 +267,8 @@ static void ubus_default_connection_lost(struct ubus_context *ctx) uloop_end(); } -struct ubus_context *ubus_connect(const char *path) +static int _ubus_connect(struct ubus_context *ctx, const char *path) { - struct ubus_context *ctx; - - ctx = calloc(1, sizeof(*ctx)); - if (!ctx) - return NULL; - ctx->sock.fd = -1; ctx->sock.cb = ubus_handle_data; ctx->connection_lost = ubus_default_connection_lost; @@ -282,7 +276,60 @@ struct ubus_context *ubus_connect(const char *path) INIT_LIST_HEAD(&ctx->requests); INIT_LIST_HEAD(&ctx->pending); avl_init(&ctx->objects, ubus_cmp_id, false, NULL); - if (ubus_reconnect(ctx, path)) { + if (ubus_reconnect(ctx, path)) + return -1; + + return 0; +} + +static void ubus_auto_reconnect_cb(struct uloop_timeout *timeout) +{ + struct ubus_auto_conn *conn = container_of(timeout, struct ubus_auto_conn, timer); + + if (!ubus_reconnect(&conn->ctx, conn->path)) + ubus_add_uloop(&conn->ctx); + else + uloop_timeout_set(timeout, 1000); +} + +static void ubus_auto_disconnect_cb(struct ubus_context *ctx) +{ + struct ubus_auto_conn *conn = container_of(ctx, struct ubus_auto_conn, ctx); + + conn->timer.cb = ubus_auto_reconnect_cb; + uloop_timeout_set(&conn->timer, 1000); +} + +static void ubus_auto_connect_cb(struct uloop_timeout *timeout) +{ + struct ubus_auto_conn *conn = container_of(timeout, struct ubus_auto_conn, timer); + + if (_ubus_connect(&conn->ctx, conn->path)) { + uloop_timeout_set(timeout, 1000); + fprintf(stderr, "failed to connect to ubus\n"); + return; + } + conn->ctx.connection_lost = ubus_auto_disconnect_cb; + if (conn->cb) + conn->cb(&conn->ctx); + ubus_add_uloop(&conn->ctx); +} + +void ubus_auto_connect(struct ubus_auto_conn *conn) +{ + conn->timer.cb = ubus_auto_connect_cb; + ubus_auto_connect_cb(&conn->timer); +} + +struct ubus_context *ubus_connect(const char *path) +{ + struct ubus_context *ctx; + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) + return NULL; + + if (_ubus_connect(ctx, path)) { free(ctx); ctx = NULL; } diff --git a/libubus.h b/libubus.h index f899ded..0c97436 100644 --- a/libubus.h +++ b/libubus.h @@ -56,6 +56,7 @@ typedef void (*ubus_data_handler_t)(struct ubus_request *req, typedef void (*ubus_complete_handler_t)(struct ubus_request *req, int ret); typedef void (*ubus_notify_complete_handler_t)(struct ubus_notify_request *req, int idx, int ret); +typedef void (*ubus_connect_handler_t)(struct ubus_context *ctx); #define UBUS_OBJECT_TYPE(_name, _methods) \ { \ @@ -188,7 +189,15 @@ struct ubus_notify_request { uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1]; }; +struct ubus_auto_conn { + struct ubus_context ctx; + struct uloop_timeout timer; + const char *path; + ubus_connect_handler_t cb; +}; + struct ubus_context *ubus_connect(const char *path); +void ubus_auto_connect(struct ubus_auto_conn *conn); int ubus_reconnect(struct ubus_context *ctx, const char *path); void ubus_free(struct ubus_context *ctx);