This can serve as a convenience for sync requets, since no explicit ubus_connect() + ubus_free() need to be done.
It can also help in cases where there are async + sync requests, where one async request is working and sync calls are done. Seems to create some weird races, probably because of possible concurrent poll() calls on the same fd. --- libubus-obj.c | 42 +++++++++++++++++++++++++++++------------- libubus-req.c | 33 ++++++++++++++++++++++++++++----- libubus-sub.c | 15 +++++++++++++-- libubus.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 112 insertions(+), 26 deletions(-) diff --git a/libubus-obj.c b/libubus-obj.c index 47bdb0a..29fe538 100644 --- a/libubus-obj.c +++ b/libubus-obj.c @@ -174,7 +174,13 @@ static bool ubus_push_object_type(const struct ubus_object_type *type) int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj) { struct ubus_request req; - int ret; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); @@ -184,22 +190,24 @@ int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj) if (obj->type->id) blob_put_int32(&b, UBUS_ATTR_OBJTYPE, obj->type->id); else if (!ubus_push_object_type(obj->type)) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; } if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_ADD_OBJECT, 0) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; req.raw_data_cb = ubus_add_object_cb; req.priv = obj; ret = ubus_complete_request(ctx, &req, 0); if (ret) - return ret; + goto out; - if (!obj->id) - return UBUS_STATUS_NO_DATA; + ret = (!obj->id) ? UBUS_STATUS_NO_DATA : 0; +out: + if (free_ctx) + ubus_free(ctx); - return 0; + return ret; } static void ubus_remove_object_cb(struct ubus_request *req, int type, struct blob_attr *msg) @@ -221,22 +229,30 @@ static void ubus_remove_object_cb(struct ubus_request *req, int type, struct blo int ubus_remove_object(struct ubus_context *ctx, struct ubus_object *obj) { struct ubus_request req; - int ret; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id); if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_REMOVE_OBJECT, 0) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; req.raw_data_cb = ubus_remove_object_cb; req.priv = obj; ret = ubus_complete_request(ctx, &req, 0); if (ret) - return ret; + goto out; - if (obj->id) - return UBUS_STATUS_NO_DATA; + ret = (!obj->id) ? UBUS_STATUS_NO_DATA : 0; +out: + if (free_ctx) + ubus_free(ctx); - return 0; + return ret; } diff --git a/libubus-req.c b/libubus-req.c index 8475dc9..240c2d4 100644 --- a/libubus-req.c +++ b/libubus-req.c @@ -225,14 +225,25 @@ int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method, { struct ubus_request req; int rc; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; rc = ubus_invoke_async(ctx, obj, method, msg, &req); if (rc) - return rc; + goto out; req.data_cb = cb; req.priv = priv; - return ubus_complete_request(ctx, &req, timeout); + rc = ubus_complete_request(ctx, &req, timeout); +out: + if (free_ctx) + ubus_free(ctx); + + return rc; } static void @@ -288,17 +299,29 @@ int ubus_notify(struct ubus_context *ctx, struct ubus_object *obj, { struct ubus_notify_request req; int ret; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; ret = __ubus_notify_async(ctx, obj, type, msg, &req, timeout >= 0); if (ret < 0) - return ret; + goto out; if (timeout < 0) { ubus_abort_request(ctx, &req.req); - return 0; + ret = 0; + goto out; } - return ubus_complete_request(ctx, &req.req, timeout); + ret = ubus_complete_request(ctx, &req.req, timeout); +out: + if (free_ctx) + ubus_free(ctx); + + return ret; } static bool ubus_get_status(struct ubus_msghdr *hdr, int *ret) diff --git a/libubus-sub.c b/libubus-sub.c index 8793133..1b51364 100644 --- a/libubus-sub.c +++ b/libubus-sub.c @@ -45,16 +45,27 @@ static int __ubus_subscribe_request(struct ubus_context *ctx, struct ubus_object *obj, uint32_t id, int type) { struct ubus_request req; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id); blob_put_int32(&b, UBUS_ATTR_TARGET, id); if (ubus_start_request(ctx, &req, b.head, type, 0) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; - return ubus_complete_request(ctx, &req, 0); + ret = ubus_complete_request(ctx, &req, 0); +out: + if (free_ctx) + ubus_free(ctx); + return ret; } int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id) diff --git a/libubus.c b/libubus.c index be4e6ac..27e3d93 100644 --- a/libubus.c +++ b/libubus.c @@ -156,18 +156,30 @@ int ubus_lookup(struct ubus_context *ctx, const char *path, ubus_lookup_handler_t cb, void *priv) { struct ubus_lookup_request lookup; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); if (path) blob_put_string(&b, UBUS_ATTR_OBJPATH, path); if (ubus_start_request(ctx, &lookup.req, b.head, UBUS_MSG_LOOKUP, 0) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; lookup.req.raw_data_cb = ubus_lookup_cb; lookup.req.priv = priv; lookup.cb = cb; - return ubus_complete_request(ctx, &lookup.req, 0); + ret = ubus_complete_request(ctx, &lookup.req, 0); +out: + if (free_ctx) + ubus_free(ctx); + + return ret; } static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_attr *msg) @@ -186,18 +198,30 @@ static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_at int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id) { struct ubus_request req; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); if (path) blob_put_string(&b, UBUS_ATTR_OBJPATH, path); if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; req.raw_data_cb = ubus_lookup_id_cb; req.priv = id; - return ubus_complete_request(ctx, &req, 0); + ret = ubus_complete_request(ctx, &req, 0); +out: + if (free_ctx) + ubus_free(ctx); + + return ret; } static int ubus_event_cb(struct ubus_context *ctx, struct ubus_object *obj, @@ -252,6 +276,13 @@ int ubus_send_event(struct ubus_context *ctx, const char *id, { struct ubus_request req; void *s; + int ret = UBUS_STATUS_INVALID_ARGUMENT; + bool free_ctx = false; + + if (!ctx) + free_ctx = (ctx = ubus_connect(NULL)) != NULL; + if (!ctx) + return -1; blob_buf_init(&b, 0); blob_put_int32(&b, UBUS_ATTR_OBJID, UBUS_SYSTEM_OBJECT_EVENT); @@ -262,9 +293,14 @@ int ubus_send_event(struct ubus_context *ctx, const char *id, blob_nest_end(&b, s); if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_INVOKE, UBUS_SYSTEM_OBJECT_EVENT) < 0) - return UBUS_STATUS_INVALID_ARGUMENT; + goto out; + + ret = ubus_complete_request(ctx, &req, 0); +out: + if (free_ctx) + ubus_free(ctx); - return ubus_complete_request(ctx, &req, 0); + return ret; } static void ubus_default_connection_lost(struct ubus_context *ctx) -- 1.8.4.5 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel