[Libwebsockets] v1.7.1

Andy Green andy at warmcat.com
Thu Feb 25 03:03:43 CET 2016



On 02/25/2016 02:30 AM, Andrejs Hanins wrote:
>
>
> On 02/24/2016 07:22 PM, Andrejs Hanins wrote:
>>
>> On 02/24/2016 06:33 PM, Andy Green wrote:
>>>
>>> On 02/24/2016 11:08 PM, Andrejs Hanins wrote:
>>>
>>>
>>>> Hmm, now I'm thinking again. When lws_close_free_wsi is called with
>>>> reason=LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY, early jump to label
>>>> just_kill_connection is made _before_ state value is copied into
>>>> state_pre_close. So the check for wsi->state_pre_close == LWSS_HTTP
>>>> is true just because default value of state_pre_close is zero. It is
>>>> not a non-upgraded connection as written in the commit comment.
>>>>
>>>> Even more strange is that when I tried to move state_pre_close
>>>> initialization to be done before jumping to just_kill_connection and
>>>> removing those two new lines which check for LWSS_HTTP, then lws
>>>> library crashes in various places.
>>>>
>>>> Andy, what do you think about it?
>>> Can you give me a way to reproduce it with the test apps +/- a hack?
>> Ok, so for the missing CLOSE callback on context destroy it is pretty easy - just add usleep(1000);
>> after lws_service(context, 500); in test-client.c code. Then run test-client and immediately terminate it
>> after connection with server is established - there will be no CLOSED callback without latest fixes.
>>
>> As for the crash - I can't reproduce it yet with test-client and test-server.
> The crash was due to my changes. I allowed CLOSED callback to be called when
> state_pre_close == LWSS_SHUTDOWN which doesn't account transient modes which
> doesn't have user space data, so it crashed while I was accessing zero pointer, so no need
> to worry.
>
> So the only questions remains - is it normal that state_pre_close is not initialized to state
> value if reason is LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY.

I think what it's trying to avoid there is multiple calls to 
lws_close_free_wsi() trashing the original wsi->state_pre_close.

Eg he might have started closing and set his state to an intermediate 
staged close one like LWSS_SHUTDOWN, then we decide to exit and destroy 
the context.  That calls lws_close_free_wsi() again, but he has not 
reached, eg

	if (wsi->state_pre_close == LWSS_ESTABLISHED ||  <<<===
	    wsi->mode == LWSCM_WS_SERVING ||
	    wsi->mode == LWSCM_WS_CLIENT) {

before because he did the shutdown wait flow and exited back to the 
event loop.

So if the second time he trashes wsi->state_pre_close with LWSS_SHUTDOWN 
that is his state by then, we won't do the right thing when we complete 
the shutdown flow.

-Andy

>>> -Andy
>



More information about the Libwebsockets mailing list