fix EBADF unqueueing in select backend (Trac #10590)
authorSergei Trofimovich <slyfox@gentoo.org>
Tue, 7 Jul 2015 15:00:23 +0000 (17:00 +0200)
committerBen Gamari <ben@smart-cactus.org>
Tue, 7 Jul 2015 17:17:43 +0000 (19:17 +0200)
commit5857e0afb5823987e84e6d3dd8d0b269b7546166
tree41c3b179e139a19a09dbf605e3a1d4aac6d8b0d7
parent9a3e1657db4c0292fc06d6183a802af631c3666a
fix EBADF unqueueing in select backend (Trac #10590)

Alexander found a interesting case:
1. We have a queue of two waiters in a blocked_queue
2. first file descriptor changes state to RUNNABLE,
   second changes to INVALID
3. awaitEvent function dequeued RUNNABLE thread to a
   run queue and attempted to dequeue INVALID descriptor
   to a run queue.

Unqueueing INVALID fails thusly:
        #3  0x000000000045cf1c in barf (s=0x4c1cb0 "removeThreadFromDeQueue: not found")
                               at rts/RtsMessages.c:42
        #4  0x000000000046848b in removeThreadFromDeQueue (...) at rts/Threads.c:249
        #5  0x000000000049a120 in removeFromQueues (...) at rts/RaiseAsync.c:719
        #6  0x0000000000499502 in throwToSingleThreaded__ (...) at rts/RaiseAsync.c:67
        #7  0x0000000000499555 in throwToSingleThreaded (..) at rts/RaiseAsync.c:75
        #8  0x000000000047c27d in awaitEvent (wait=rtsFalse) at rts/posix/Select.c:415

The problem here is a throwToSingleThreaded function that tries
to unqueue a TSO from blocked_queue, but awaitEvent function
leaves blocked_queue in a inconsistent state while traverses
over blocked_queue:

      case RTS_FD_IS_READY:
          IF_DEBUG(scheduler,
              debugBelch("Waking up blocked thread %lu\n",
                         (unsigned long)tso->id));
          tso->why_blocked = NotBlocked;
          tso->_link = END_TSO_QUEUE;              // Here we break the queue head
          pushOnRunQueue(&MainCapability,tso);
          break;

Signed-off-by: Sergei Trofimovich <siarheit@google.com>
Test Plan: tested on a sample from T10590

Reviewers: austin, bgamari, simonmar

Reviewed By: bgamari, simonmar

Subscribers: qnikst, thomie, bgamari

Differential Revision: https://phabricator.haskell.org/D1024

GHC Trac Issues: #10590, #4934
rts/RaiseAsync.c
rts/RaiseAsync.h
rts/posix/Select.c
testsuite/tests/rts/T10590.hs [new file with mode: 0644]
testsuite/tests/rts/all.T