[GHC] #13497: GHC does not use select()/poll() correctly on non-Linux platforms

GHC ghc-devs at haskell.org
Thu Mar 30 20:43:52 UTC 2017


#13497: GHC does not use select()/poll() correctly on non-Linux platforms
-------------------------------------+-------------------------------------
        Reporter:  nh2               |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Runtime System    |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #8684, #12912     |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by nh2):

 Actually before that, I should probably fix the Windows version too (for
 the case that the FD is not a socket).

 https://github.com/ghc/ghc/blob/f46369b8a1bf90a3bdc30f2b566c3a7e03672518%5E/libraries/base/cbits/inputReady.c#L80

 {{{
 while (1) // keep trying until we find a real key event
 {
   rc = WaitForSingleObject( hFile, msecs );
   ...
 }}}

 Looking at this, it is not clear to me how this should ever have worked
 (how this should have provided the semantics that after the maximum given
 time, `hWaitForInput` returns), as this would simply loop forever if
 interrupted by a signal.

 I just wrote the above sentence and then realised that the exact same was
 true for any non-Linux select, so I got suspicious why it worked at all so
 far on my FreeBSD VM before my fix, because any EINTR should just return
 out of `fdReady()` just to have it restarted with the original full
 duration.

 [1 hour later]

 I now know what's going on. It only worked on non-Linux because of the
 idle GC!

 Looking at `truss`, it keeps calling `select()` until suddenly a
 `ktimer_settime` appears, and a quick `printf` reveals that it's issued by
 `stopTicker()` called by `stopTimer()` caused by idle GC. When the idle GC
 is set to a value larger than the `msecs` passed to `fdReady()`, e.g. when
 `msecs = 500` and `+RTS -I1`, then `fdReady` will never return and the
 program will be stuck.

 BSD and Mac OS users (and probably Windows) were just lucky so far that
 idle GC defaults to 0.3 seconds.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13497#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list