[Libwebsockets] libev

Andy Green andy at warmcat.com
Fri Dec 5 18:11:11 CET 2014



On 5 December 2014 20:50:59 GMT+08:00, Alejandro Mery <amery at geeks.cl> wrote:
>On Fri, Dec 05, 2014 at 08:37:09PM +0800, Andy Green wrote:
>> 
>> 
>> On 5 December 2014 19:17:38 GMT+08:00, Alejandro Mery
><amery at geeks.cl> wrote:
>> >On Fri, Dec 05, 2014 at 07:20:05AM +0800, Andy Green wrote:
>> >> 
>> >> 
>> >> On 5 December 2014 00:49:19 GMT+08:00, Alejandro Mery
>> ><amery at geeks.cl> wrote:
>> >> >Hi,
>> >> >
>> >> >I need to integrate a libwebsocket client connection into an
>> >existing
>> >> >ev_loop, but from what I see it the libev integration is still
>very
>> >> >incomplete and just hacked in. so I need to finish it.
>> >> 
>> >> Great it was contributed, I guess that's all he needed.
>> >> 
>> >> >does it make sense to keep the polling hooks when using libev?
>maybe
>> >> >implementing it as a separated plat instead of a ton of #ifdef-s?
>> >any
>> >> >pointer on the preferred direction how I should approach it?
>> >> 
>> >> plat-blah is used to mop up differences like windows vs unix, the
>> >underlying technique is good though.
>> >> 
>> >> Something we need to take care about is a "distro build config"
>that
>> >makes it possible to use different options in one library binary,
>> >rather than rely on buildtime options for everything.  Because
>> >different apps using lws may have conflicting build-time
>requirements,
>> >but the distro will only ship one library built one way.
>> >> 
>> >> So a good mix would be yes, use event-libev.c, event-poll.c etc
>> >selectable at buildtime, but they would not be mutually exclusive,
>you
>> >could select a cmake to build in all of them.  Create an "ops"
>struct
>> >that defines function pointers for every job that can be done by the
>> >event implementations
>> >> 
>> >> struct lws_event_ops {
>> >>      int (*lws_event_job1)(blah);
>> >>      ...
>> >> }
>> >> 
>> >> and each implementation file exports their ops like
>> >> 
>> >> struct lws_event_ops lws_event_ops_poll {
>> >>     lws_event_job1_poll,
>> >>     ....
>> >> };
>> >> 
>> >> and in the info struct used to create the context, and the context
>> >itself we add a member
>> >> 
>> >> struct lws_event_ops *event_ops;
>> >> 
>> >> if NULL in info at context creation time, it's set to
>> >lws_event_ops_poll by default.  If the app wants to specify the
>event
>> >system to use, he sets the member in info to one of the exported ops
>> >structs from the event implementation files.
>> >> 
>> >> When some come needs to get the event implementation to do
>something,
>> >he calls like
>> >> 
>> >> context->event_ops->lws_event_job1(...);
>> >> 
>> >> Does it sound reasonable?
>> >
>> >in principle yes, but for example the mapping between fd and swi
>> >(connection manager?) is most likely also handled by the same
>module.
>> >should I do a different lws_foo_ops for those?
>> 
>> If I understood... at the moment there's a very efficient fd - wsi
>mapping it can make sense to support something else but it'd need to be
>at least similarly efficient (I have no idea what the event libs
>support for this).
>> 
>
>the thing is that using libev you can get the `struct libwebsocket *`
>either doing container_of() magic over the pointer to the watcher, or
>explicitly storing it in `w->data` and that affects the entire
>paradigm.
>
>similar thing applies to other event backends

It affects the paradigm because it hides the cost of the actual fd -> event object lookup in the event library, but the raw material for the wait inside the event library is still an fd.  I can see after hiding it there's no problem getting from the composed event object to the wsi.  I guess you'll just have to see where it leads.

>> >considering most structs are opaque, does it make sense to
>> >export a function to "initialize" the &info from within event-foo.o
>?
>> >the initialization for each event module is very likely to need
>> >different things.
>> 
>> An ops.lws_event_init or whatever sounds ok if useful but the info
>init data should maybe be set by the user code.  If he has some struct
>ev * or whatever he wants to pass in by info the user code has to have
>that as a struct ev * at thst point, so it shouldn't make trouble.
>> 
>
>sadly ops.lws_event_init doesn't work because different event backends
>will need different arguments, at least a pointer of the right type
>for the event loop struct they will be using.

If the ops.init() is basically preparing the new event union member in the wsi, you might find passing the union itself as the arg to ops.init() will fit well.

>> >also, how to include the fields needed by each in context and wsi? a
>> >union of specialized structs or following the current approach of
>> >adding more direct fields? (same question for &info)
>> 
>> Yes, a union of structs for all supported private data should do it
>both for per-instance storage and init via &info re-using the same
>union.  Need to make sure related stuff only gets included in the union
>if the support was enabled for build, so in the degenerate case only
>poll is available, the rest doesn't get included anywhere so no build
>problems are coming.
>> 
>
>ok
>
>
>> I guess 80% of it is completing converting poll + libev to work under
>this scheme pretty much unchanged.
>> 
>
>yes... well.. sort of. the current libev implementation is broken for
>client
>connections :p    but initially is just refactoring/convering both,
>yes.

Okay no need to port the breakage ^^  sounds like a plan.

-Andy

>cheers,
>Alejandro Mery




More information about the Libwebsockets mailing list