<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>