<div dir="ltr">Forgot to add Github link for easier review.<br><br><a href="https://github.com/commodo/ubus/commit/f8942190ea7ff4a243410aa0a9d38eacd41d0b4a">https://github.com/commodo/ubus/commit/f8942190ea7ff4a243410aa0a9d38eacd41d0b4a</a><br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jul 17, 2014 at 6:25 PM, Alexandru Ardelean <span dir="ltr"><<a href="mailto:ardeleanalex@gmail.com" target="_blank">ardeleanalex@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This can serve as a convenience for sync requets, since no explicit<br>
ubus_connect() + ubus_free() need to be done.<br>
<br>
It can also help in cases where there are async + sync requests,<br>
where one async request is working and sync calls are done.<br>
Seems to create some weird races, probably because of possible<br>
concurrent poll() calls on the same fd.<br>
<br>
---<br>
libubus-obj.c | 42 +++++++++++++++++++++++++++++-------------<br>
libubus-req.c | 33 ++++++++++++++++++++++++++++-----<br>
libubus-sub.c | 15 +++++++++++++--<br>
libubus.c | 48 ++++++++++++++++++++++++++++++++++++++++++------<br>
4 files changed, 112 insertions(+), 26 deletions(-)<br>
<br>
diff --git a/libubus-obj.c b/libubus-obj.c<br>
index 47bdb0a..29fe538 100644<br>
--- a/libubus-obj.c<br>
+++ b/libubus-obj.c<br>
@@ -174,7 +174,13 @@ static bool ubus_push_object_type(const struct ubus_object_type *type)<br>
int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)<br>
{<br>
struct ubus_request req;<br>
- int ret;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
<br>
@@ -184,22 +190,24 @@ int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)<br>
if (obj->type->id)<br>
blob_put_int32(&b, UBUS_ATTR_OBJTYPE, obj->type->id);<br>
else if (!ubus_push_object_type(obj->type))<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
}<br>
<br>
if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_ADD_OBJECT, 0) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
<br>
req.raw_data_cb = ubus_add_object_cb;<br>
req.priv = obj;<br>
ret = ubus_complete_request(ctx, &req, 0);<br>
if (ret)<br>
- return ret;<br>
+ goto out;<br>
<br>
- if (!obj->id)<br>
- return UBUS_STATUS_NO_DATA;<br>
+ ret = (!obj->id) ? UBUS_STATUS_NO_DATA : 0;<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
<br>
- return 0;<br>
+ return ret;<br>
}<br>
<br>
static void ubus_remove_object_cb(struct ubus_request *req, int type, struct blob_attr *msg)<br>
@@ -221,22 +229,30 @@ static void ubus_remove_object_cb(struct ubus_request *req, int type, struct blo<br>
int ubus_remove_object(struct ubus_context *ctx, struct ubus_object *obj)<br>
{<br>
struct ubus_request req;<br>
- int ret;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id);<br>
<br>
if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_REMOVE_OBJECT, 0) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
<br>
req.raw_data_cb = ubus_remove_object_cb;<br>
req.priv = obj;<br>
ret = ubus_complete_request(ctx, &req, 0);<br>
if (ret)<br>
- return ret;<br>
+ goto out;<br>
<br>
- if (obj->id)<br>
- return UBUS_STATUS_NO_DATA;<br>
+ ret = (!obj->id) ? UBUS_STATUS_NO_DATA : 0;<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
<br>
- return 0;<br>
+ return ret;<br>
}<br>
diff --git a/libubus-req.c b/libubus-req.c<br>
index 8475dc9..240c2d4 100644<br>
--- a/libubus-req.c<br>
+++ b/libubus-req.c<br>
@@ -225,14 +225,25 @@ int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method,<br>
{<br>
struct ubus_request req;<br>
int rc;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
rc = ubus_invoke_async(ctx, obj, method, msg, &req);<br>
if (rc)<br>
- return rc;<br>
+ goto out;<br>
<br>
req.data_cb = cb;<br>
req.priv = priv;<br>
- return ubus_complete_request(ctx, &req, timeout);<br>
+ rc = ubus_complete_request(ctx, &req, timeout);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
+<br>
+ return rc;<br>
}<br>
<br>
static void<br>
@@ -288,17 +299,29 @@ int ubus_notify(struct ubus_context *ctx, struct ubus_object *obj,<br>
{<br>
struct ubus_notify_request req;<br>
int ret;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
ret = __ubus_notify_async(ctx, obj, type, msg, &req, timeout >= 0);<br>
if (ret < 0)<br>
- return ret;<br>
+ goto out;<br>
<br>
if (timeout < 0) {<br>
ubus_abort_request(ctx, &req.req);<br>
- return 0;<br>
+ ret = 0;<br>
+ goto out;<br>
}<br>
<br>
- return ubus_complete_request(ctx, &req.req, timeout);<br>
+ ret = ubus_complete_request(ctx, &req.req, timeout);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
+<br>
+ return ret;<br>
}<br>
<br>
static bool ubus_get_status(struct ubus_msghdr *hdr, int *ret)<br>
diff --git a/libubus-sub.c b/libubus-sub.c<br>
index 8793133..1b51364 100644<br>
--- a/libubus-sub.c<br>
+++ b/libubus-sub.c<br>
@@ -45,16 +45,27 @@ static int<br>
__ubus_subscribe_request(struct ubus_context *ctx, struct ubus_object *obj, uint32_t id, int type)<br>
{<br>
struct ubus_request req;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id);<br>
blob_put_int32(&b, UBUS_ATTR_TARGET, id);<br>
<br>
if (ubus_start_request(ctx, &req, b.head, type, 0) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
<br>
- return ubus_complete_request(ctx, &req, 0);<br>
+ ret = ubus_complete_request(ctx, &req, 0);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
<br>
+ return ret;<br>
}<br>
<br>
int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)<br>
diff --git a/libubus.c b/libubus.c<br>
index be4e6ac..27e3d93 100644<br>
--- a/libubus.c<br>
+++ b/libubus.c<br>
@@ -156,18 +156,30 @@ int ubus_lookup(struct ubus_context *ctx, const char *path,<br>
ubus_lookup_handler_t cb, void *priv)<br>
{<br>
struct ubus_lookup_request lookup;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
if (path)<br>
blob_put_string(&b, UBUS_ATTR_OBJPATH, path);<br>
<br>
if (ubus_start_request(ctx, &lookup.req, b.head, UBUS_MSG_LOOKUP, 0) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
<br>
lookup.req.raw_data_cb = ubus_lookup_cb;<br>
lookup.req.priv = priv;<br>
lookup.cb = cb;<br>
- return ubus_complete_request(ctx, &lookup.req, 0);<br>
+ ret = ubus_complete_request(ctx, &lookup.req, 0);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
+<br>
+ return ret;<br>
}<br>
<br>
static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_attr *msg)<br>
@@ -186,18 +198,30 @@ static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_at<br>
int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)<br>
{<br>
struct ubus_request req;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
if (path)<br>
blob_put_string(&b, UBUS_ATTR_OBJPATH, path);<br>
<br>
if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
<br>
req.raw_data_cb = ubus_lookup_id_cb;<br>
req.priv = id;<br>
<br>
- return ubus_complete_request(ctx, &req, 0);<br>
+ ret = ubus_complete_request(ctx, &req, 0);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
+<br>
+ return ret;<br>
}<br>
<br>
static int ubus_event_cb(struct ubus_context *ctx, struct ubus_object *obj,<br>
@@ -252,6 +276,13 @@ int ubus_send_event(struct ubus_context *ctx, const char *id,<br>
{<br>
struct ubus_request req;<br>
void *s;<br>
+ int ret = UBUS_STATUS_INVALID_ARGUMENT;<br>
+ bool free_ctx = false;<br>
+<br>
+ if (!ctx)<br>
+ free_ctx = (ctx = ubus_connect(NULL)) != NULL;<br>
+ if (!ctx)<br>
+ return -1;<br>
<br>
blob_buf_init(&b, 0);<br>
blob_put_int32(&b, UBUS_ATTR_OBJID, UBUS_SYSTEM_OBJECT_EVENT);<br>
@@ -262,9 +293,14 @@ int ubus_send_event(struct ubus_context *ctx, const char *id,<br>
blob_nest_end(&b, s);<br>
<br>
if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_INVOKE, UBUS_SYSTEM_OBJECT_EVENT) < 0)<br>
- return UBUS_STATUS_INVALID_ARGUMENT;<br>
+ goto out;<br>
+<br>
+ ret = ubus_complete_request(ctx, &req, 0);<br>
+out:<br>
+ if (free_ctx)<br>
+ ubus_free(ctx);<br>
<br>
- return ubus_complete_request(ctx, &req, 0);<br>
+ return ret;<br>
}<br>
<br>
static void ubus_default_connection_lost(struct ubus_context *ctx)<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4.5<br>
<br>
</font></span></blockquote></div><br></div>