[Libwebsockets] Example of custom event loop integration?

Andy Green andy at warmcat.com
Sun May 30 13:47:45 CEST 2021

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[0] 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.

> Many Perl applications run their own select/poll loop. It’s not performant, but it is what it is. I’d like to support that rather than requiring users to use libev, libuv, etc. (which may not be available if they lack compiler access).


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


More information about the Libwebsockets mailing list