threadWaitRead works incorrectly on nonthreaded RTS
I found out it in xmobar on ghc-7.0.1. When I ran it I got the following message:
xmobar: file descriptor 8954336 out of range for select (0--1024).
Recompile with -threaded to work around this.
-threaded option works, but the message is absolutely misleading.
I've decided to track where so large descriptor could come, but there was no such place.
All xmobar does is:
do x11connection_fd <- connectionNumber d
threadWaitRead (Fd fd) -- here we die
x11connection_fd has value 3 at the time of call. This value comes from libX11 (via FFI, so I suspect it's a problem).
Another example (might be unrelated):
-- a.hs
import Control.Concurrent
-- 12 is picked at random as guaranteed to be invalid FD
main = threadWaitRead 12 >> print "yet input!"
Building:
$ ghc --make -fforce-recomp a.hs -o a
[1 of 1] Compiling Main ( a.hs, a.o )
Linking a ...
$ ghc --make -fforce-recomp a.hs -threaded -o a.threaded
[1 of 1] Compiling Main ( a.hs, a.o )
Linking a.threaded ...
Running:
$ ./a.threaded
a.threaded: epollControl: invalid argument (Bad file descriptor)
Looks good.
And nonthreaded:
$ ./a
"yet input!"
According to strace there was an error but it was not reported.
sf tmp # strace -etrace='select,write' ./a >/dev/null
select(13, [12], [], NULL, {134, 217727}) = -1 EBADF (Bad file descriptor) # this one
select(2, [], [1], NULL, {0, 0}) = 1 (out [1], left {0, 0})
write(1, "\"yet input!\"\n", 13) = 13
Side note: Haskeline seems to workaround this problem on it's own way.
libraries/haskeline/System/Console/Haskeline/Backend/Posix.hsc
-- Different versions of ghc work better using different functions.
blockUntilInput :: Handle -> IO ()
#if __GLASGOW_HASKELL__ >= 611
-- threadWaitRead doesn't work with the new ghc IO library,
-- because it keeps a buffer even when NoBuffering is set.
blockUntilInput h = hWaitForInput h (-1) >> return ()
#else
-- hWaitForInput doesn't work with -threaded on ghc < 6.10
-- (#2363 in ghc's trac)
blockUntilInput h = unsafeHandleToFd h >>= threadWaitRead
#endif
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Unknown/Multiple |
Architecture | Unknown/Multiple |