[Libwebsockets] lws_service_adjust_timeout & lws_service_flag_pending

Andy Green andy at warmcat.com
Mon Mar 15 13:37:50 CET 2021

On 3/15/21 12:24 PM, Bram Peeters wrote:
> Hi,
>> Maybe I am just having a rough day but I don't see what you describe in the code.
> Probably I am misunderstanding then.
>  From the your link (my version is a few months old now but it seems unchanged)  there is
> A)The part where n gets the free heap size if timeout expired:
>                  unsigned long m = lws_now_secs();
>                  if (m > context->time_last_state_dump) {
>                          context->time_last_state_dump = m;
> #if defined(LWS_ESP_PLATFORM)
>                          n = esp_get_free_heap_size();
> #else
>                          n = xPortGetFreeHeapSize();
> #endif
> 		<...>
>                          }
>                  }
> B) The part where this value for n is used in case lws_service_adjust_timeout and  lws_service_flag_pending both return 0:
>          m = lws_service_flag_pending(context, tsi);
>          if (m)
>                  c = -1; /* unknown limit */
>          else
>                  if (n < 0) {

Oh.... that doesn't look right....

>                          if (LWS_ERRNO != LWS_EINTR)
>                                  return -1;
>                          return 0;
>                  } else
>                          c = n;
> So either it exits, or c becomes the free heap size( the latter does not cause much problems, since there is also a check in the loop to limit the number anyway, n < (int)pt->fds_count )
> Did I miss a part ?

No, my eyes slid over it... thanks for pointing it out, it looks like it 
needs some cleaning...

>> Also, I would not use EXTERNAL_POLL if I could at all avoid it.
>   I saw another post earlier today with a discussion that it is 'outdated' (https://github.com/warmcat/libwebsockets/issues/1841).
> I need to look further into it, but the https://libwebsockets.org/git/libwebsockets/tree/lib/event-libs  documentation you refer too there seems to be about libev/libuv/libevent which  I assume is for systems with Linux/Windows/... OSes. Or should that also be applicable for Freertos based systems ?

"External Poll" is trying to share the wait, it's never going to make a 
satisfying solution.  If no pending events that it knows about, the 
event loop, lws default loop or any event library loop, wants to 
maximize the time the service thread is asleep and waiting for events. 
In other words it wants to block for as long as possible so it doesn't 
waste cpu or power.

EXTERNAL_POLL introduces a perverse motivation that we want to give some 
other code some time on the thread at intervals... so we can never allow 
the lws service loop to spend very long blocked.  If we allow no block 
time, we spin at 100% of one core all the time.  As we allow more 
blocking time, the latency between times we lend cpu to the 
EXTERNAL_POLL task is increased... if that takes up cpu time, it 
increases latency for servicing socket traffic.

It depends on what the other code you're trying to share the thread with 
does, but, eg, you can use lws_sul nowadays to get callbacks to random 
functions at random times, scheduled entirely on the lws event loop cleanly.

If the other code is also handling socket traffic, there may be a way to 
use raw lws wsis to handle it also on the event loop.


More information about the Libwebsockets mailing list