MantisBT - OCaml
View Issue Details
0007665OCamlplatform support (windows, cross-compilation, etc)public2017-11-02 19:442018-09-02 10:16
gabelevi 
 
normalminoralways
newopen 
win32Windows 10 Enterprise1511
4.03.0 
 
0007665: Unix.select with a mix of sockets and non-sockets is not level triggered on Windows
I'm using 4.03.0+mingw64 https://fdopen.github.io/opam-repository-mingw/2016/05/03/ocaml_4_03/ [^]

Unix.select should be "level triggered". That is, as long as a fd is ready, it should be returned. This is opposed to being "edge triggered", where the fd would only be returned when it first becomes ready.

On Windows, Unix.select with a mixture of sockets and non-sockets does not return all of the ready fds consistently. The first call behaves correctly, but subsequent calls don't.
I uploaded a script which demonstrates the problem, by selecting both a socket and stdin. For some reason, Unix.select stops reporting the socket as being ready. I ran it on cygwin

$ echo "hello" | ocaml C:/cygwin64/home/glevi/.opam/4.03.0+mingw64c/lib/ocaml/unix.cma testA.ml
Set up socket

Socket is not yet connected, so only stdin should be ready
stdin is ready
sock is not ready

Connected to socket

Now they both should be ready
stdin is ready
sock is ready

But if we call select again we hit the bug
stdin is ready
sock is not ready

And it repros if we call again
stdin is ready
sock is not ready

Individually stdin is readable: true

Individually sock is readable: true

But together it is still buggy
stdin is ready
sock is not ready
No tags attached.
? testA.ml (1,674) 2017-11-02 19:44
https://caml.inria.fr/mantis/file_download.php?file_id=1720&type=bug
? test.ml (1,777) 2018-09-01 16:36
https://caml.inria.fr/mantis/file_download.php?file_id=1749&type=bug
Issue History
2017-11-02 19:44gabeleviNew Issue
2017-11-02 19:44gabeleviFile Added: testA.ml
2018-09-01 16:36tootsNote Added: 0019324
2018-09-01 16:36tootsNote Edited: 0019324bug_revision_view_page.php?bugnote_id=19324#r3313
2018-09-01 16:36tootsFile Added: test.ml
2018-09-01 16:39tootsNote Edited: 0019324bug_revision_view_page.php?bugnote_id=19324#r3314
2018-09-02 02:50tootsNote Added: 0019327

Notes
(0019324)
toots   
2018-09-01 16:36   
(edited on: 2018-09-01 16:39)
I can confirm that, too. Seen here with a mixture of pipe and network socket. Attached is a minimal script reproducing my case. It happens in a complex scheduling context (liquidsoap) and would be great to see fixed..

Tested with versions: 4.01 & 4.07 so it's been around for a while.

(0019327)
toots   
2018-09-02 02:50   
I believe this is the relevant documentation about the underlying call:

"The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first connected with a call to the connect, ConnectEx, WSAConnect, WSAConnectByList, or WSAConnectByName function or when a socket is accepted with accept, AcceptEx, or WSAAccept function and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set."