[vlc-devel] [PATCH] win32: use the same poll code as libcurl

Steve Lhomme robux4 at gmail.com
Mon Nov 30 19:06:45 CET 2015


"On Mon, Nov 30, 2015 at 10:44 AM, Steve Lhomme <robux4 at gmail.com> wrote:
> On Sat, Nov 28, 2015 at 3:16 PM, Rémi Denis-Courmont <remi at remlab.net> wrote:
>> On Thursday 26 November 2015 16:43:15 Steve Lhomme wrote:
>>>  A workaround is to close the httpd
>>> connection before joining the thread that's doing the listening. But
>>> that should be done in other places too that assume select() is
>>> alertable.
>>
>> No. Closing a file descriptor in use by another thread is not portable, and it
>> is intrinsically racy:
>>
>> - Owner thread calls closesocket().
>> - Polling thread calls select().
>> -> gets EBADF.
>>
>> Or worse:
>>
>> - Owner thread calls closesocket().
>> - Unrelated thread create a new socket, gets the same handle.
>> - Owner thread calls join().
>> - Polling thread calls select().
>> -> Polling thread waits on an innocent socket.
>> -> Owner thread jams.
>>
>>> Is there a reason we mix select() and WSAEventSelect() in the current
>>> master ?
>>
>> AFAIR without the select() call, the poll() level-triggered semantics are not
>> abode by so events sometimes can get lost depending on the call site.
>
> I understand the code better now. I wonder if there's a race issue
> between the moment we call select() and the moment we call
> WSAEnumNetworkEvents() or some of the further WSA calls. If I add
> enough logs in poll(), effectively extending the time between calls, I
> do not get the issue I'm having anymore. Otherwise I get the issue
> 100% of the time.

I think I understand the issue I'm having. It has to do with the mix
of WSAEnumNetworkEvents() and select().

The process goes as follows:
- register an event to receive FD_WRITE
- select() the socket and look if we can write (yes there's room)
- WSAEnumNetworkEvents() reports FD_WRITE is set
- unregister the event and close it
- send() data

at this point we lost the FD_WRITE event

- register an event to receive FD_WRITE
- select() the socket and look if we can write (yes there's room)
- WSAEnumNetworkEvents() reports FD_WRITE is no set
- unregister the event and close it
- send() data

< keep writing until select() says there's no room >

- register an event to receive FD_WRITE
- select() the socket and look if we can write (no room left)
- WSAEnumNetworkEvents() reports FD_WRITE is no set
- no room so wait with WSAWaitForMultipleEvents() until we have a
FD_WRITE event.

That event never happens.


>> --
>> Rémi Denis-Courmont
>> http://www.remlab.net/
>>
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list