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

Alexandru Ardelean ardeleanalex at gmail.com
Fri Apr 3 04:15:07 EDT 2015


In this case you have 2 solutions:
1) use some sync / lock mechanism in cwmp's callback as you've said
2) you can try to adapt some general solution that would work in ubus and
submit a patch upstream; I think Felix would have to give an opinion here
first

I can't think of any other solutions at the moment.


On Fri, Apr 3, 2015 at 10:38 AM, XiaoFengMeng <xiaofeng.meng at pfsw.com>
wrote:

>  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.
>
>
>
> Thanks.
>
>
>
> *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>
> 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) {
>
>                 uloop_init();
>
>                 ubus_add_uloop(ctx);
>
> }
>
>
>
> I experimented on this, it seems working well,
>
> I like to know what’s your opinion on this?
>
>
>
> Thanks!
>
> /Kevin
>
> *From:* Alexandru Ardelean [mailto:ardeleanalex at gmail.com]
> *Sent:* 2015年4月3日 14:20
> *To:* XiaoFengMeng
> *Cc:* 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>
> 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) {
>
>                                 uloop_init();
>
>                                 ubus_add_uloop(ctx);
>
> }
>
> ….
>
> 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);
>
>                                                                 break;
>
>                                                 }
>
>                                 }
>
>                                 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
>
> Kevin
>
>
>
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20150403/6cb23b79/attachment.htm>
-------------- next part --------------
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list