[Libwebsockets] lws_service_adjust_timeout & lws_service_flag_pending

Bram Peeters Bram.Peeters at dekimo.com
Mon Mar 15 13:46:43 CET 2021


Ok, thank you for the feedback. 
I need to a dig a little deeper into the code / documentation I think to understand all the implications but the top level idea it a bit clearer now.

Have a nice day!
Bram
-----Original Message-----
From: Andy Green <andy at warmcat.com> 
Sent: Monday, March 15, 2021 13:38
To: Bram Peeters <Bram.Peeters at dekimo.com>; libwebsockets at ml.libwebsockets.org
Subject: Re: [Libwebsockets] lws_service_adjust_timeout & lws_service_flag_pending



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.

-Andy



More information about the Libwebsockets mailing list