Using libubus from foreign code (seems impossible)

I've been digging into libubus, because I need it to track events, but it appears to have two issues. One is that it's not really asynchronous: it seems to call poll() itself, and also start its own event loops. And of course it's tightly integrated with libubox, even though it's not using libubox's asynchronous behavior in a systematic way.

What this means is that (1) I can't integrate it into my event loop without peeling out the libubox dependency, and (2) if I peel out the libubox dependency, calls to libubus can still block.

I'm seriously contemplating fixing this, but before I do, I'd like anybody who reads this and understands it to fight me on the topic of whether this is necessary. Am I just missing something here, or have others run into this as well?

I don't think there's any C api users of libubus that do not use libubox at the same time, so likely nobody met this limitation yet or worked on a fix for this.

On the usage of libubox; this is used for calloc_a() as well as linked list and AVL tree helpers and not for the event loop functions.

I think it is not necessary to decouple libubox just to implement an asynchronous api. It is perfectly fine to link and use libubox helpers without using uloop at all.

I don't think it's necessary to decouple libubox to get asynchronous behavior either. Making it asynchronous using libubox would be my first step. However, I do not want libubus to require the use of the libubox I/O loop, because I want to be able to use it in code that already has an I/O loop, where it would be exceedingly painful to switch to libubux as the I/O loop.

IOW, the way I would want this to work is that libubus by default uses libubox, but is able to use some other I/O loop implementation without having to be recompiled: the libubox I/O loop calls would go through an adaptation layer.

Oh, FWIW libubus definitely does use the libubox event loop calls. If you look at libubus-io.c you can see this. It's not clear to me yet what it's doing, but that's where this is coming from.

Ah indeed, I missed those. Anyhow, my point still stands. It makes sense to offer an async api which does not touch uloop, but using the libubox library for other purposes (calloc_a, avl trees, linked list primitives) etc. would still be fine.

I understood your initial post as if you plan to rip out the use of libubox completely, which likely wouldn't make much sense.

That could work with moderate effort I suppose. Maybe simply add the possibility to register a struct of function pointers with event loop operations (.add, .remove etc.) which could be optionally used instead of the default uloop implementations.

Yes, that's what I had in mind. No need to rip out libubox! :slight_smile:

I was also deeply disappointed by the ubus / ubox behavior.

I would be interested in collaborating on improvements to this with you.