Cope with ThreadRelocated when traversing the blocked_queue
authorSimon Marlow <marlowsd@gmail.com>
Thu, 6 Nov 2008 11:40:45 +0000 (11:40 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 6 Nov 2008 11:40:45 +0000 (11:40 +0000)
Fixes "invalid what_next field" in ioref001 on Windows, and perhaps others

rts/posix/Select.c
rts/win32/AsyncIO.c

index ae9c717..bf4b7ae 100644 (file)
@@ -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);
index 6fb9a2b..1b57d37 100644 (file)
@@ -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) ) {