[Libwebsockets] Modifying libwebsocket.user_space

Roger Light roger at atchoo.org
Tue Aug 19 12:15:15 CEST 2014


On Tue, Aug 19, 2014 at 1:28 AM, Andy Green <andy at warmcat.com> wrote:
>
>
> On 19 August 2014 00:58:24 GMT+08:00, Roger Light <roger at atchoo.org> wrote:
>>Hi,
>>
>>I'm in the situation where events outside of lws may require me to
>>update the contents of the user_space member of a single struct
>>libwebsocket. Any suggestions on how to proceed?
>>
>>I have a struct that represents a client in my application. It keeps a
>>pointer to the wsi struct.
>>
>>The easiest solution from my point of view would be the creation of a
>>libwebsocket_get_user() function. I see that this has been discussed
>>before (e.g.
>>http://ml.libwebsockets.org/pipermail/libwebsockets/2013-February/000240.html
>>) and dismissed. I understand the reasoning there, but at least in my
>>case if service had cleaned up and freed the wsi, then my client
>>struct would also have been freed and I wouldn't be in this situation.
>>This is all single threaded, right? :)
>
> After a rough start trying to work with people with multithreaded apps, it's
> boiled down that it should be safe to call the on_writeable() callback for a
> wsi externally, from an external wsi list that is maintained by following the
> ESTABLISHED and CLOSED callbacks.
>
> So generally, on_writeable() is threadsafe and that's enough to move all the
> other processing back into the service thread context ON_WRITEABLE
> callback; from there you can write websockets data or do whatever else you need.

I wasn't clear - I meant that my own code is single threaded - "This
is all single threaded so I should always know the state of each wsi
anyway". With that the case, a call to a new libwebsocket_get_user()
to get access to the specific user_space member I'm interested would
be safe.

> Some people have a huge number of clients connected, so this is an
> expensive call for them.  If all connected clients do it just aimed at
> themselves you end up with the square of (number of clients - 1) wasted
> callbacks; number of clients can be > 10000.

I quite agree and I'm trying to cater to lots of clients. I was just
trying to work with points you've made in the past. It's certainly my
second least favourite option, but there you go. The function I'm
suggesting already exists, just without the capability of passing an
"in" value.

> If you follow the ESTABLISHED and CLOSED callbacks to enforce your
> other wsi list's lifetime (with locking if multithreaded), and the only thing
> you use it for is asking for a writeable callback, then you shouldn't get
> any bad wsi access.

Yes, I'm confident that this is the case.

> Then you can just use a member in your *user struct to deliver the pointer
> or whatever it is you want processed.

This is the bit I'm stuck on. I don't have access to my user struct
outside of the lws callback function. If I did, I could just
manipulate it however I wanted. I could keep a duplicate pointer to
the user struct for each client, but that seems a bit of a waste and
if you're happy with that then it seems as though providing a
libwebsocket_get_user() function is basically the same thing, but cuts
down on a pointer in my client struct.

Cheers,

Roger



More information about the Libwebsockets mailing list