[OpenWrt-Devel] Question about conflict between ubus_invoke and uloop_run

XiaoFengMeng xiaofeng.meng at pfsw.com
Fri Apr 3 03:38:51 EDT 2015

Hi Alex,
Thanks you the suggestion.
My situation is more complicated than what you think.

I am using a third-part cwmp library, and a lots of callbacks are registered into the lib, which are used to get values of data models. The cwmp lib has its own working thread, and callback will be called in that thread, we have to use ubus to get the value from another daemon program in the callback, and the callback should return the value directly.

Meanwhile, we have our main thread, in which we need to receive ubus event and messages from the system.

So it is impossible to have only one thread  to handle everything, we can’t modify the code  of third-part lib.


From: Alexandru Ardelean [mailto:ardeleanalex at gmail.com]
Sent: 2015年4月3日 15:11
To: XiaoFengMeng
Cc: openwrt-devel at lists.openwrt.org
Subject: Re: [OpenWrt-Devel] Question about conflict between ubus_invoke and uloop_run

Yes, you have to use ubus_invoke_sync() in this case.
You can use ubus_invoke_async() and re-design your code using a state-machine mechanism.
This would simplify the need to add any locks & syncs.

You should not use directly:
ctx->ubus->sock.registered = true;
It could complicate things long-term.
To conclude : I think the best idea is to use a state-machine .
Whenever your callback function is called you call into the state machine.
Depending on the current state, you can execute actions, including changing states if needed.
I'd say that if you do this, you can remove that separate thread.

On Fri, Apr 3, 2015 at 9:41 AM, XiaoFengMeng <xiaofeng.meng at pfsw.com<mailto:xiaofeng.meng at pfsw.com>> wrote:
HI Alexandru

Thanks so much for your reply!
In my case, the ubus_invoke will be called in a callback function which is in a separate thread, and uloop_run will be running in  main thread.
If I have to use ubus_invoke_async, then I feel that I have to use a lock to sync the call.

And I think you confirmed with an idea of mine:
if I want to use “ubus_invoke”,  “uloop_run” can’t be used at the same time,
or if I use uloop_run, I have to use ubus_invoke_async instread.

Is that right?

But I just got a tricky way of using ubus_invoke and uloop_run at the same time.
For the ubus context which is only used to call ubus_invoke as client, I set the registered of usock to true,
ctx->ubus->sock.registered = true;

actually this socket is not added to uloop in reality, I do this so that following code in ubus_complete_request function will not be executed.
And thus no conflict with uloop.
if (!registered) {

I experimented on this, it seems working well,
I like to know what’s your opinion on this?

From: Alexandru Ardelean [mailto:ardeleanalex at gmail.com<mailto:ardeleanalex at gmail.com>]
Sent: 2015年4月3日 14:20
To: XiaoFengMeng
Cc: openwrt-devel at lists.openwrt.org<mailto:openwrt-devel at lists.openwrt.org>
Subject: Re: [OpenWrt-Devel] Question about conflict between ubus_invoke and uloop_run

Hello Kevin,
As far as my understanding goes regarding ubus and uloop, they were not designed with threading in mind.
Also, as a general rule when using uloop, you wouldn't use threads, because races could occur (especially when doing ubus calls inside a thread) and the main uloop loop would terminate.

One general rule would be: you should not use ubus call in threads.
You could use ubus_invoke_async() instead of ubus_invoke().
It is a bit more work than just using ubus_invoke() but if you want thread-like behaviour, it could replace all the threads you're using.

So, is there a way to re-design your code without using threads and using ubus async calls ?

On Fri, Apr 3, 2015 at 5:24 AM, XiaoFengMeng <xiaofeng.meng at pfsw.com<mailto:xiaofeng.meng at pfsw.com>> wrote:
HI !
I am Kevin and learning the ubus code and got something that is confusing me very much in the code.

My question is regarding code in  ubus_invoke -> ubus_complete_request,

I can see that there are lots of uloop related code in  “ubus_complete_request”
if (!registered) {
while (!req->status_msg) {
                                bool cancelled = uloop_cancelled;

                                uloop_cancelled = false;
                                if (req_timeout) {
                                                timeout = time_end - get_time_msec();
                                                if (timeout <= 0) {
                                                                ubus_set_req_status(req, UBUS_STATUS_TIMEOUT);
                                ubus_poll_data(ctx, (unsigned int) timeout);

                                uloop_cancelled = cancelled;

My question is why is uloop involved here?  uloop could be working in another thread and also listen on the same socket.
I idea that, before the ubus_invoke sends the request messge, it should disable the uloop for the current socket, so that code in uloop_run will not receive anything from the same socket.

Because after calling ubus_add_uloop(ctx), the uloop_run could also be receiving the response data
And this function could cause the uloop_run to quit the while loop.
How should I understand the logic here?

And How should I do if I want to call ubus_invoke as a client and use uloop_run as a server at  the same process?

Thanks very much!

Best regards

openwrt-devel mailing list
openwrt-devel at lists.openwrt.org<mailto:openwrt-devel at lists.openwrt.org>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20150403/a3003887/attachment.htm>
-------------- next part --------------
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org

More information about the openwrt-devel mailing list