[Libwebsockets] Example of custom event loop integration?
felipe at felipegasper.com
Sun May 30 14:46:28 CEST 2021
> On May 30, 2021, at 7:47 AM, Andy Green <andy at warmcat.com> wrote:
> On 5/30/21 12:25 PM, Felipe Gasper wrote:
>>> On May 30, 2021, at 1:35 AM, Andy Green <andy at warmcat.com> wrote:
>>> On 5/30/21 1:21 AM, Felipe Gasper wrote:
>>> Hi Felipe -
>>>> I’m considering writing a Perl binding to libwebsockets. For this to work I need to be able to integrate libwebsockets into whatever event loop the Perl application runs. (There are many loops, and three widely-used abstraction interfaces over them.)
>>>> I found the HTTP-server foreign event lib integration example: https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-server/minimal-http-server-eventlib-foreign/minimal-http-server-eventlib-foreign.c
>>>> This example, though, appears only to use event libraries that libwebsockets natively supports. Does libwebsockets include an interface like libcurl’s multi_socket interface (cf. https://curl.se/libcurl/c/libcurl-multi.html)? That seems to be what `struct lws_event_loop_ops` and `struct lws_plugin_evlib` represent … are there any examples of giving these structs to libwebsockets at runtime?
>>> For custom loops in the application, there is a gnarly hack from a decade ago it sounds like you found, the EXTERNAL_POLL support, I really don't recommend using this. Modern lws offers hi res scheduling services (for, eg, UDP retry) that are used internally and encouraged for user code, since it radically improves portability, that are coming from modulating the wait via event lib timers or timeout computation. EXTERNAL_POLL's concept was much dumber, just bringing a zero-wait service call inside an existing custom event loop, it cannot make a satisfying result for both latency and cpu load. It also has a dependency on protocols which is user code business, and not available for the kind of generic integration you are looking at.
>> Ah, ok. So best to avoid EXTERNAL_POLL if possible.
> Right, it's off by default at cmake. I would mark it deprecated but people are still using it from a long time ago.
>> So, is there a supported/recommended mechanism that allows an application to do its own custom polling without recompiling libwebsockets to include a custom plugin? To start/stop libwebsockets as part of that custom loop? Is there an example somewhere?
> No. As I said:
> >> ... passing a struct lws_event_loop_ops * in at context creation time is easy to add.
> if you think that will do you, I can add it. But that api is not exactly designed for hacking in someone's random existing poll wait, it's designed to allow integration of these complicated event libs at the right spots.
> What I can imagine is an event lib plugin that exposes a way user code can register a simpler "ops" struct with function callbacks to get stuff done on an external fd wait. But at a minimum, the existing wait is going to have to check with us to learn the max wait timeout for its poll(), and understand which fds are ours and handle them differently.
> Another way to do it would be add apis in lws that allow the app to register its own fds to participate on the lws wait, be it the default poll() one or handled by an event lib. Then we can take care of which fds have external handlers and which belong to lws.
I’m not experienced enough with LWS to feel confident in offering an opinion on its architecture. But once/if such a method is added I’ll be interested in making this library available in Perl. (I may do so anyway, just with the requirement to use one of the supported event loops.) All of the WebSocket solutions in Perl that I know of are pure-Perl; having a C implementation would be a boon on multiple levels.
It would also facilitate bindings in other languages; for example, Twisted (Python) does its own select/poll/epoll by default.
More information about the Libwebsockets