[Libwebsockets] 答复: a question about poll timeout change in libwebsockets.

huangkaicheng huangkaicheng at huawei.com
Mon Jun 8 10:29:56 CEST 2020


Hi,
   Because lws is not thread safe. In some service case, we make that lws to execute safely in another thread. We add MutexLock to ensure lws is safe as follows.

In thread A(network thread):
    ....
    g_wsContext = lws_create_context(&info);
   while (retCode >= 0 && !g_bForceExit) {
        MutexLock(&g_stWebSocketMutex);
        retCode = lws_service(g_wsContext, RTC_TRANS_LOOP_SLEEP_TIME);
        MutexUnLock(&g_stWebSocketMutex);
        SleepMs(RTC_TRANS_LOOP_SLEEP_TIME);
    }

In thread B(service thread):
    ...
    MutexLock(&g_stWebSocketMutex);
    struct lws_client_connect_info connectInfo;
    (VOS_VOID)memset_s(&connectInfo, sizeof(struct lws_client_connect_info), 0, sizeof(struct lws_client_connect_info));
    connectInfo.address = linkInfo->serverAddr;
    connectInfo.context = g_wsContext;
    connectInfo.port = (int)info->port;
    connectInfo.ssl_connection = (int)info->bUseSsl;
    connectInfo.origin = linkInfo->serverAddr;
    connectInfo.host = info->domain;
    connectInfo.path = info->url;
    connectInfo.protocol = NULL;
    connectInfo.ietf_version_or_minus_one = ietfVersion;
    wsi = lws_client_connect_via_info(&connectInfo);

    MutexUnLock(&g_stWebSocketMutex);
   ....

In stable 2.3, it work well. And in stable4.0 it work well also. But we meet sometime lws_client_connect_via_info will not execute immediately util ws_service is return.
And we found lws_service return is wait utils poll is timeout. So lws_client_connect_via_info may be waited up to 1000ms because "mute lock"(in fact, there is nothing todo). We need lws_service is return quickly if there is nothing todo so that lws_client_connect_via_info can be execute quickly. In stable 2.3, timeout is setted by lws_service,so lws_client_connect_via_info is executed quickly.
    Can you understand what I described and give a suggest for a better way please? 

-----邮件原件-----
发件人: Andy Green [mailto:andy at warmcat.com] 
发送时间: 2020年6月6日 12:11
收件人: huangkaicheng <huangkaicheng at huawei.com>; libwebsockets <libwebsockets at ml.libwebsockets.org>
抄送: Chenyake <chenyake at huawei.com>
主题: Re: a question about poll timeout change in libwebsockets.



On 6/6/20 4:43 AM, huangkaicheng wrote:
> Hi,
> 
>     I have a question, In 2.3version, timeout_ms of poll is setted by 
> lws_service(struct lws_context *context, int timeout_ms)directly as 
> follows;
> 
> and In stable 4.0 version, it has changed as follows. What is 
> consideration for the changes of timeout. If timeout_ms is still 
> setted by lws_service(struct lws_context *context, int timeout_ms) in 
> 4.0 stable, it will OK?
> 
> we found timeout is up to 1000ms sometimes.

In v3.2+, the poll wait timeout can be up to two weeks if nothing to do. 
  The point is as soon as "something to do", a network event or a scheduled event on the event loop, he immediately wakes up and does it. 
He only remains sleeping if nothing to do.

In older lws, it requires to wake every second or so and check timeouts.

At v3.2, I rewrote how time works inside lws to use lws_sul, a sorted list of future schedules events that is inexpensive to maintain

https://libwebsockets.org/git/libwebsockets/tree/READMEs/README.lws_sul.md

this gives a lot of new capabilities, applications can schedule any number of arbitrary callbacks at us resolution from the event loop thread context, they don't have to use the protocol callback any more.

In addition, lws adjusts the poll wait timeout to the *earliest* scheduled event... the scheduler list is sorted so this is very cheap to find out.  That means that the time spent asleep in the poll wait is maximized which is a good behaviour for system power.

In master (soon to be v4.1) this is further extended to two sorted lists, one as before and the other containing events capable to wake the system from suspend.  So it is also easy to discover how long to set the suspend wake timer of your system.

This increasingly aligns the poll() event management with all the other event libs... if you build against libuv or whatever, lws_service() never returns until the context is destroyed.

In short you shouldn't try to fit things around lws_service() because eventually, it will behave like all the other event loops and not return until the context is destroyed.  If you describe what you're trying to do with that I can try to suggest a better way.

-Andy


More information about the Libwebsockets mailing list