[Libwebsockets] polling for file descriptor i/o

Andy Green andy at warmcat.com
Sun Mar 5 00:39:05 CET 2017



On March 5, 2017 5:59:01 AM GMT+08:00, Per Bothner <per at bothner.com> wrote:
>On 03/04/2017 12:14 PM, Andy Green wrote:
>
>>> The flow should be
>>>
>>> - notified of rx on file fd
>>> - set the parent flag and ask for writeable callback on parent
>>> - lws_rx_flow_control(wsi, 0); to disable POLLIN / rx notifications
>>>
>>> - notified of parent writeable
>>> - read child and send data
>>> - lws_rx_flow_control(wsi_child, 1);  to allow more rx on child file
>fd
>
>I tried that, and I haven't gotten it to work.  However:
>>
>> Dunno if it is interesting, but eventually you might also want to
>look at the mirror test protocol approach as well
>
>>
>https://github.com/warmcat/libwebsockets/blob/master/plugins/protocol_lws_mirror.c
>>
>> He supports one-to-many by adding a FIFO that is fed in the file fd
>RX (the read happens right there in this approach) and the ws clients
>draw down the fifo at their own speeds.  RX flow control is only used
>then to protect the fifo from overflowing.
>>
>> That way you can offer sharing the pty remotely to n clients.
>
>Long-term, I would like to include the functionality of the 'screen'
>program, including detachable and multi-user sessions.  However, it
>will
>have to wait.  For one, it depends on me understand certificates and
>related security issues better.  For another, there are other "big"
>features I want to focus on first (better input editing a la readline;
>a builtin less-like pager).
>
>But this does suggest that having the read from the pty fd be to be
>done in RAW_RX_FILE callback
>(not the SERVER_WRITEABLE callback) might be the more future-proof
>approach.
>
>Plus the little detail that I actually have that working ...

Is it ok if multiple rx come before the remote side becomes writeable?  Mirror can do that safely only because he has a fifo and ultimately rx flow control to manage when he will get new rx.  So he never gets rx with nowhere to put it.

Without that since rx can come when it likes you can get a system that is fragile against real-world network links where the remote connection becoming writeable in effect races the next rx coming.

If you will do the read in the rx callback and buffer it, it's ok but the rx flow control stuff is mandatory.  Doing the read in the writable callback lets you eliminate the memory for the per-connection bulk data buffer, but otherwise the same.


BTW I am still going on the zip integration... I can't use mmap since some platforms we support don't have it.  So several iterations of optimization have ended up with libz stuff directly being called from zip_fops, no storage of the zip index in memory, that suggested other improvements to fops like generic file position and length held there, that has other knock-ons.  I also have implemented chunked inflate, so it does not require memory to inflate the whole file any more, but does it piecemeal like permessage-deflate, and seeking (although it is expensive since it restarts the inflate and inflates its way to the seek point).

The last problem yesterday was I changed the code to use really virtual file paths, like /var/www/docs/manual.zip/index.html... that looks like it will require adding fstat to the fops, since lws serving code wants fstat it before opening it.

I'll continue with it today.

-Andy




More information about the Libwebsockets mailing list