[Libwebsockets] How to set the "user" callback parameter for adopted sockets?

Andy Green andy at warmcat.com
Thu Nov 24 17:02:17 CET 2016



On November 24, 2016 11:25:20 PM GMT+08:00, Alan Conway <aconway at redhat.com> wrote:
>On Thu, 2016-11-24 at 23:10 +0800, Andy Green wrote:
>> 
>> On November 24, 2016 10:42:02 PM GMT+08:00, Alan Conway <aconway at redh
>> at.com> wrote:
>> > 
>> > On Wed, 2016-11-23 at 23:19 +0800, Andy Green wrote:
>> > > 
>> > > 
>> > > On November 23, 2016 10:53:57 PM GMT+08:00, Alan Conway <aconway@
>> > > redh
>> > > at.com> wrote:
>> > > > 
>> > > > 
>> > > > On Wed, 2016-11-23 at 09:46 -0500, Alan Conway wrote:
>> > > > > 
>> > > > > 
>> > > > > On Wed, 2016-11-23 at 08:50 +0800, Andy Green wrote:
>> > > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > > On Tue, 2016-11-22 at 19:02 -0500, Alan Conway wrote:
>> > > > > > > 
>> > > > > > > 
>> > > > > > > 
>> > > > > > > 
>> > > > > > > I'm making progress! I can crash my router from a web
>> > > > > > > brower
>> > > > > > > :)
>> > > > > > > 
>> > > > > > > I can't figure out how to set the "user" parameter for
>> > > > > > > lws
>> > > > > > > callbacks
>> > > > > > > for a socket adopted with lws_adopt_socket(). I can
>> > > > > > > access
>> > > > > > > the
>> > > > > > 
>> > > > > > That's not what *user_space is for.
>> > > > > > 
>> > > > > > It's for protocol-specific local data, per-
>> > > > > > connection.  When
>> > > > > > the
>> > > > > > protocol changes, which it may often do with a http/1.1
>> > > > > > keepalive
>> > > > > > connection visiting urls that map on to different plugins,
>> > > > > > the
>> > > > > > user
>> > > > > > data allocation is destroyed by lws and a new one sized
>> > > > > > appropriately
>> > > > > > for the new protocol allocated.
>> > > > > 
>> > > > > For me, the protocol starts as "http" and may change to
>> > > > > "binary"
>> > > > > or
>> > > > > "amqp" (which I treat as both "amqp"). Does that mean that if
>> > > > > I
>> > > > > store
>> > > > > context for the http protocol, it will be wiped out in the
>> > > > > upgrade?
>> > > > > Is
>> > > > > there any way to preserve some per-connection data between
>> > > > > the
>> > > > > two or
>> > > > > is each protocol session treated as entirely separate from
>> > > > > previous
>> > > > > ones?
>> > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > > > 
>> > > > > > > 
>> > > > > > > 
>> > > > > > > 
>> > > > > > > allocated space *after* the adopt call with
>> > > > > > > lws_wsi_user(),
>> > > > > > > but
>> > > > > > > lws_adopt_socket() itself is firing my callbacks so
>> > > > > > > that's
>> > > > > > > too
>> > > > > > > late.
>> > > > > > > 
>> > > > > > > The docs mention setting up your session data on the
>> > > > > > > LWS_CALLBACK_ESTABLISHED event, but at that point I have
>> > > > > > > nothing
>> > > > > > > I
>> > > > > > > can
>> > > > > > > use to find data from my application.
>> > > > > > 
>> > > > > > LWS doesn't have this concept of external shadowed data
>> > > > > > per-
>> > > > > > connection
>> > > > > > built-in.
>> > > > > > 
>> > > > > > You have two ways to do it
>> > > > > > 
>> > > > > >  - add a new opaque void * in struct lws and set it at
>> > > > > > adopt-
>> > > > > > time,
>> > > > > > provide an accessor to get it from the wsi.  This is a bit
>> > > > > > of a
>> > > > > > burden
>> > > > > > for everyone who doesn't care about this then.
>> > > > > 
>> > > > > For current purposes I need to use a released, packaged
>> > > > > version
>> > > > > of
>> > > > > lws
>> > > > > so modifying it isn't an option - I do hope to make
>> > > > > contributions
>> > > > > later...
>> > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > > 
>> > > > > >  - Set the context user pointer at context creation
>> > > > > > time.  You
>> > > > > > can
>> > > > > > get
>> > > > > > this from a wsi in the callback.  You can then use this
>> > > > > > context-
>> > > > > > wide
>> > > > > > pointer to dereference the wsi pointer to your private
>> > > > > > connection
>> > > > > > pointer on your side, entirely outside of lws.
>> > > > > 
>> > > > > I could use either the fd or the wsi pointer to look up my
>> > > > > application
>> > > > > data, but it's an expensive lookup that requires a map of all
>> > > > > the
>> > > > > known
>> > > > > fds/wsi-pointers. I could use thread-local storage as a hack
>> > > > > to
>> > > > > get
>> > > > > my
>> > > > > context into the initial "http" established callback, but
>> > > > > that
>> > > > > doesn't
>> > > > > help if it will get wiped out in the upgrade to "amqp"...
>> > > > > Hmmm.
>> > > > > 
>> > > > 
>> > > > What if I use a separate context per connection? I know you
>> > > > said I
>> > > 
>> > > No, that is a very bad idea.
>> > 
>> > Why? What will go wrong?
>> 
>> Did you look at what goes on in the context + vhost structs you will
>> be spawning one of per connection to see why it's a bad idea?
>> 
>
>OK, so am I safe to call lws_process_fd() for different fds on the same
>shared context concurrently? If so then a lookup table of some sort for

Why don't you go back up our email exchanges to where you airily wrote off the multiple service thread support without understanding what it was, and re-read my explanation of why it's done like that and what it buys you in terms of safe concurrency.

>the application data will work. If there's any chance of race on the
>context then I'd rather waste memory than figure out the race
>conditions - in the short term.

Lws has been around for six years before your specific usecase appeared.

The context contains processwide things like lookups of all process fds.  There are several potentially big mallocs (lws supports huge numbers of fds if that's what your process has) when you create the context.  Post v1.7, at least one vhost is created when you create the context.  The openssl context object is created with the context!  You will do all that per-connection?

I mean if the author of the library is telling you, "don't do that", is it reasonable to continue discussing it?

>I know there are better solutions if we modify lws, but not for my
>upcoming release.

It is not a member of the set of solutions.

-Andy

>Cheers,
>Alan.




More information about the Libwebsockets mailing list