[Libwebsockets] Fwd: Is a callback guaranteed after calling libwebsocket_callback_on_writable_all_protocol ?

Andy Green andy at warmcat.com
Tue Mar 14 02:25:31 CET 2017



On March 14, 2017 5:58:49 AM GMT+08:00, Simon Schmid <simon at at-point.ch> wrote:
>2017-03-13 18:06 GMT+01:00 Andy Green <andy at warmcat.com>:
>>
>>
>> Yeah... this is the same way as the mirror example protocol.
>>
>
>Yep... the mirror protocol comes very close to what I need.
>
>> >Another option would be to enumerate all connected clients and
>adjust
>> >the
>> >tail pointers as I insert into the ring buffer. But I haven't found
>a
>> >way
>> >to enumerate all connected clients, is there one?
>>
>> The ...all_protocol() type apis effectively do this.
>>
>
>I just checked `lws_callback_all_protocol` function, but it also says
>"When: when the individual connection becomes writeable" in the
>documentation, which means it's also not guaranteed I get a callback in
>the
>next service?

It's a cut-and-paste mistake in the comment... that api calls them right away, not at the next service.

But this is almost never what you want, the 'when writable' reflects the basic regulation of sending data on the connection.  And the only time you need to touch wsi-specific data is when you read or write it, which have their own callback driven by network events.

>> Otherwise you don't need it... at the time the connection becomes
>writable, you know that connection's last written tail, if you maintain
>a
>counter instead of a pointer the MSBs of it will know how many samples
>missed from FIFO overflow in the interim and you can deal with skipping
>forward for that individual connection.
>>
>
>This assumes the ringbuffer has not cycled through completely, i.e the
>number of missed entries is less than the ringbuffer's capacity. Let's

Eh... no.

If your counters are 32-bit but the ringbuffer contains say 4K elements, b12 and above are the "MSB" I mentioned, b11..0 is the position inside the ringbuffer.  So long as it didn't miss out on 4G elements, which you can guarantee by setting a timeout on the connection, you can subtract the connection tail counter from that of the head and know about the absolute number of elements to catch up.  If it's greater than the size of the ringbuffer, you know you have to skip.

>assume the client was in a tunnel and gets writeable again after the
>producer has written as many elements as the ringbuffer's capacity. In
>the
>callback it now looks like the client is up-to-date and we send him the
>newest entry, although it would have been more optimal to choose the
>oldest
>entry.
>
>An absolute counter which increases monotonically could solve this
>partially because it can measure the number of missed entries over many
>laps. When we get the callback and the number of missed entries is
>larger
>than the ringbuffers capacity, we know the optimal position to start
>reading is the oldest entry. However this introduces another issue when
>the
>counter itself wraps around, after 2^32 or 2^64 counts.

No... (0x00000000 - 0xffffffff) is 1 in 32b arithmetic, subtracting tail from head continues to work as one or the other wraps.  If you still worry about it, don't reset your counters to 0 but to 0xfffff000 or similar so you are always testing the boundary.

-Andy



More information about the Libwebsockets mailing list