add auto (re)connect logic to libubus

Signed-off-by: John Crispin <blogic@openwrt.org>
This commit is contained in:
John Crispin 2014-01-22 13:53:11 +00:00
parent 8ea9667036
commit 29d7092252
2 changed files with 64 additions and 8 deletions

View file

@ -267,6 +267,60 @@ static void ubus_default_connection_lost(struct ubus_context *ctx)
uloop_end(); uloop_end();
} }
static int _ubus_connect(struct ubus_context *ctx, const char *path)
{
ctx->sock.fd = -1;
ctx->sock.cb = ubus_handle_data;
ctx->connection_lost = ubus_default_connection_lost;
INIT_LIST_HEAD(&ctx->requests);
INIT_LIST_HEAD(&ctx->pending);
avl_init(&ctx->objects, ubus_cmp_id, false, NULL);
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 *ubus_connect(const char *path)
{ {
struct ubus_context *ctx; struct ubus_context *ctx;
@ -275,14 +329,7 @@ struct ubus_context *ubus_connect(const char *path)
if (!ctx) if (!ctx)
return NULL; return NULL;
ctx->sock.fd = -1; if (_ubus_connect(ctx, path)) {
ctx->sock.cb = ubus_handle_data;
ctx->connection_lost = ubus_default_connection_lost;
INIT_LIST_HEAD(&ctx->requests);
INIT_LIST_HEAD(&ctx->pending);
avl_init(&ctx->objects, ubus_cmp_id, false, NULL);
if (ubus_reconnect(ctx, path)) {
free(ctx); free(ctx);
ctx = NULL; ctx = NULL;
} }

View file

@ -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_complete_handler_t)(struct ubus_request *req, int ret);
typedef void (*ubus_notify_complete_handler_t)(struct ubus_notify_request *req, typedef void (*ubus_notify_complete_handler_t)(struct ubus_notify_request *req,
int idx, int ret); int idx, int ret);
typedef void (*ubus_connect_handler_t)(struct ubus_context *ctx);
#define UBUS_OBJECT_TYPE(_name, _methods) \ #define UBUS_OBJECT_TYPE(_name, _methods) \
{ \ { \
@ -188,7 +189,15 @@ struct ubus_notify_request {
uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1]; 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); 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); int ubus_reconnect(struct ubus_context *ctx, const char *path);
void ubus_free(struct ubus_context *ctx); void ubus_free(struct ubus_context *ctx);