From 1d5ac421a5b3dca60562e876ba70d0c2fe46b3d2 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 18 Mar 2014 22:36:36 +0100 Subject: [PATCH] libubus: do not use uloop_run() inside ubus_complete_request Avoid unrelated uloop callbacks by using poll() on the ubus fd instead. Signed-off-by: Felix Fietkau --- libubus-internal.h | 2 ++ libubus-io.c | 11 +++++++++++ libubus-req.c | 42 +++++++++++++++++++++--------------------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/libubus-internal.h b/libubus-internal.h index c50e7fd..6b40d7e 100644 --- a/libubus-internal.h +++ b/libubus-internal.h @@ -27,5 +27,7 @@ int __hidden ubus_start_request(struct ubus_context *ctx, struct ubus_request *r void ubus_process_obj_msg(struct ubus_context*ctx, struct ubus_msghdr *hdr); void ubus_process_req_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr, int fd); void ubus_process_pending_msg(struct ubus_context *ctx); +void __hidden ubus_poll_data(struct ubus_context *ctx, int timeout); + #endif diff --git a/libubus-io.c b/libubus-io.c index 030d382..9a6c7cd 100644 --- a/libubus-io.c +++ b/libubus-io.c @@ -264,6 +264,17 @@ void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events) ctx->connection_lost(ctx); } +void __hidden ubus_poll_data(struct ubus_context *ctx, int timeout) +{ + struct pollfd pfd = { + .fd = ctx->sock.fd, + .events = POLLIN | POLLERR, + }; + + poll(&pfd, 1, timeout); + ubus_handle_data(&ctx->sock, ULOOP_READ); +} + static void ubus_refresh_state(struct ubus_context *ctx) { diff --git a/libubus-req.c b/libubus-req.c index 79e5643..cdb8393 100644 --- a/libubus-req.c +++ b/libubus-req.c @@ -114,38 +114,32 @@ static void ubus_sync_req_cb(struct ubus_request *req, int ret) uloop_end(); } -struct ubus_sync_req_cb { - struct uloop_timeout timeout; - struct ubus_request *req; -}; - -static void ubus_sync_req_timeout_cb(struct uloop_timeout *timeout) +static int64_t get_time_msec(void) { - struct ubus_sync_req_cb *cb; + struct timespec ts; + int64_t val; - cb = container_of(timeout, struct ubus_sync_req_cb, timeout); - ubus_set_req_status(cb->req, UBUS_STATUS_TIMEOUT); + clock_gettime(CLOCK_MONOTONIC, &ts); + val = (int64_t) ts.tv_sec * 1000LL; + val += ts.tv_nsec / 1000000LL; + return val; } int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req, - int timeout) + int req_timeout) { - struct ubus_sync_req_cb cb; ubus_complete_handler_t complete_cb = req->complete_cb; bool registered = ctx->sock.registered; int status = UBUS_STATUS_NO_DATA; + int64_t timeout = 0, time_end = 0; if (!registered) { uloop_init(); ubus_add_uloop(ctx); } - if (timeout) { - memset(&cb, 0, sizeof(cb)); - cb.req = req; - cb.timeout.cb = ubus_sync_req_timeout_cb; - uloop_timeout_set(&cb.timeout, timeout); - } + if (req_timeout) + time_end = get_time_msec() + req_timeout; ubus_complete_request_async(ctx, req); req->complete_cb = ubus_sync_req_cb; @@ -153,17 +147,23 @@ int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req, ctx->stack_depth++; while (!req->status_msg) { bool cancelled = uloop_cancelled; + uloop_cancelled = false; - uloop_run(); + if (req_timeout) { + timeout = time_end - get_time_msec(); + if (timeout <= 0) { + ubus_set_req_status(req, UBUS_STATUS_TIMEOUT); + break; + } + } + ubus_poll_data(ctx, (unsigned int) timeout); + uloop_cancelled = cancelled; } ctx->stack_depth--; if (ctx->stack_depth) uloop_cancelled = true; - if (timeout) - uloop_timeout_cancel(&cb.timeout); - if (req->status_msg) status = req->status_code; -- 2.11.0