Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0004466OCamlOCaml windowspublic2007-12-12 07:532014-07-31 17:30
Reporteromion 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusacknowledgedResolutionopen 
PlatformOSOS Version
Product Version3.10.0 
Target Versionafter-4.02.0Fixed in Version 
Summary0004466: Unix.select on Windows not handling reads and writes to same socket
DescriptionI am making a program which constantly listens on a socket for incoming data, in order to check for timeouts, but Unix.select seems to act strange on Windows. It will not register a socket available for reading if it was written to after it started listening. Since that sentence doesn't make sense, here's a layout:

1. One thread runs "Unix.select [socket] [] [] timeout"
2. Another thread writes out to the socket
3. Data is received from a remote program

In this case, the "select" function should return as soon as 3. occurs. In Linux and OSX, this is exactly what happens. However it always times out in Windows.
Additional InformationThe attached files demonstrate the problem. The receiver simply responds to all incoming data. The sender sends three "packets":
The first packet is sent before the select occurs
The second and third packets are sent right after a select is started up
Compile the files separately. I used
ocamlopt -o send3-timeout -thread unix.cmxa threads.cmxa send3-timeout.ml
and
ocamlopt -o recv3-timeout -thread unix.cmxa threads.cmxa recv3-timeout.ml

Then run the receiver in one window:
recv3-timeout 45678
And the sender in another:
send3-timeout 127.0.0.1:45678

Under Linux, the sender returns with the following:
Selected after 0.000013 seconds
Selected after 0.052056 seconds
Selected after 0.052001 seconds

However, in Windows it returns the following:
Selected after 0.016000 seconds
TIMEOUT after 10.000000 seconds
Selected after 0.000000 seconds

Under Windows, the second select fails, but the second response is picked up immediately by the third select.
TagsNo tags attached.
Attached Fileszip file icon select-test.zip [^] (1,670 bytes) 2007-12-12 07:53

- Relationships

-  Notes
(0004386)
omion (reporter)
2007-12-12 07:54

And... I just realized I selected "Caml-light" for the submission. This actually occurs in OCaml 3.10.0 for Windows.
(0004407)
omion (reporter)
2008-01-09 21:32

In the meantime, I made a nasty hack that can get around this issue. I made a socketpair called (fake_in, fake_out) (not easy in Windows since the Unix.socketpair is not supported) which I use to "reset" the select.

Whenever I write something to the real socket, I write to fake_in as well. Then I use the following for the select statement:
select [fake_out;real_sock] [] [] timeout

This will return fake_out whenever something was written to the real socket, so I can re-run the select statement and not have the problem.

However, right around the time I added this statement in the program, it started crashing (it comes up with the Windows "do you want to debug?" dialog). I have no idea if it is related, but it looks fishy.
(0005045)
Christoph Bauer (reporter)
2009-08-14 12:06
edited on: 2009-08-14 15:42

seems to be solved with ocaml >= 3.11.0.

Selected after 0.000000 seconds
Selected after 0.063000 seconds
Selected after 0.047000 seconds

Tested with the patch from 0004844.

Updated: On the other hand in a more complex program I see also
such a strange behaviour. I do something like
select [sock] [] [sock] 1.0
No timeout
select [] [sock] [sock] 1.0
No timeout
select [sock] [] [sock] 1.0
timeout
select [sock] [] [sock] 1.0
No timeout (exactly 0.0s)

Update II:
The problem indeed seems to be, that sock is used twice in my select calls.
There is a difference if the third list is empty.

(0010760)
omion (reporter)
2013-12-22 07:21

I'm making another program which would run into this bug, but it looks like it's fixed if the new[*] select function (from revision 10467, I think) is used.

For the Unix.select line in send3-timeout.ml:
match Unix.select [sock] [] [] timeout with

I added Unix.stdin:
match Unix.select [sock] [] [Unix.stdin] timeout with

This forces the new function, returning good values:
Selected after 0.000000 seconds
Selected after 0.062000 seconds
Selected after 0.062000 seconds

It's still a bit hackish, since I have no idea if/when Unix.stdin would actually be selected with an exception, but it seems to work...


[*] Well... "new" in relation to this bug report. I guess that function's 3 years old already.

- Issue History
Date Modified Username Field Change
2007-12-12 07:53 omion New Issue
2007-12-12 07:53 omion File Added: select-test.zip
2007-12-12 07:54 omion Note Added: 0004386
2008-01-09 21:32 omion Note Added: 0004407
2008-01-10 11:23 doligez Status new => acknowledged
2008-01-10 11:23 doligez Category Caml-light => OCaml general
2009-08-14 12:06 Christoph Bauer Note Added: 0005045
2009-08-14 12:49 Christoph Bauer Note Edited: 0005045
2009-08-14 15:38 Christoph Bauer Note Edited: 0005045
2009-08-14 15:42 Christoph Bauer Note Edited: 0005045
2010-04-18 20:35 xleroy Status acknowledged => assigned
2010-04-18 20:35 xleroy Assigned To => gildor
2012-07-11 16:01 doligez Target Version => 4.01.0+dev
2012-07-31 13:37 doligez Target Version 4.01.0+dev => 4.00.1+dev
2012-09-15 11:34 doligez Target Version 4.00.1+dev => 4.00.2+dev
2012-09-15 11:35 doligez Assigned To gildor =>
2012-09-15 11:35 doligez Status assigned => acknowledged
2013-07-09 14:06 doligez Category OCaml general => OCaml windows
2013-07-09 14:06 doligez Target Version 4.00.2+dev => 4.01.0+dev
2013-07-24 22:28 doligez Target Version 4.01.0+dev => 4.01.1+dev
2013-12-22 07:21 omion Note Added: 0010760
2014-05-25 20:20 doligez Target Version 4.01.1+dev => 4.02.0+dev
2014-07-31 17:30 doligez Target Version 4.02.0+dev => after-4.02.0


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker