From b877faddc0cce7cceb470861a084784e0c1073b0 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Thu, 6 Nov 2008 11:40:45 +0000 Subject: [PATCH] Cope with ThreadRelocated when traversing the blocked_queue Fixes "invalid what_next field" in ioref001 on Windows, and perhaps others --- rts/posix/Select.c | 5 +++++ rts/win32/AsyncIO.c | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rts/posix/Select.c b/rts/posix/Select.c index ae9c717..bf4b7ae 100644 --- a/rts/posix/Select.c +++ b/rts/posix/Select.c @@ -244,6 +244,11 @@ awaitEvent(rtsBool wait) if (select_succeeded || unblock_all) { for(tso = blocked_queue_hd; tso != END_TSO_QUEUE; tso = next) { next = tso->_link; + + if (tso->what_next == ThreadRelocated) { + continue; + } + switch (tso->why_blocked) { case BlockedOnRead: ready = unblock_all || FD_ISSET(tso->block_info.fd, &rfd); diff --git a/rts/win32/AsyncIO.c b/rts/win32/AsyncIO.c index 6fb9a2b..1b57d37 100644 --- a/rts/win32/AsyncIO.c +++ b/rts/win32/AsyncIO.c @@ -275,8 +275,21 @@ start: unsigned int rID = completedTable[i].reqID; prev = NULL; - for(tso = blocked_queue_hd ; tso != END_TSO_QUEUE; prev = tso, tso = tso->_link) { + for(tso = blocked_queue_hd ; tso != END_TSO_QUEUE; tso = tso->_link) { + if (tso->what_next == ThreadRelocated) { + /* Drop the TSO from blocked_queue */ + if (prev) { + setTSOLink(&MainCapability, prev, tso->_link); + } else { + blocked_queue_hd = tso->_link; + } + if (blocked_queue_tl == tso) { + blocked_queue_tl = prev ? prev : END_TSO_QUEUE; + } + continue; + } + switch(tso->why_blocked) { case BlockedOnRead: case BlockedOnWrite: @@ -311,6 +324,8 @@ start: } break; } + + prev = tso; } /* Signal that there's completed table slots available */ if ( !ReleaseSemaphore(completed_table_sema, 1, NULL) ) { -- 1.7.10.4