X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fposix%2FSelect.c;h=3c87fbdc70ee66ec16024f4abfb03f6b9022f721;hb=890f22ef8eff8dbb5b31fa221dfce65a7b84c202;hp=0dbacef7a816a175351c35efea530c8fcddda861;hpb=f9e1c2af8fdd112019a657e66b0cd685d8df66f6;p=ghc-hetmet.git diff --git a/rts/posix/Select.c b/rts/posix/Select.c index 0dbacef..3c87fbd 100644 --- a/rts/posix/Select.c +++ b/rts/posix/Select.c @@ -6,18 +6,20 @@ * * ---------------------------------------------------------------------------*/ -/* we're outside the realms of POSIX here... */ -/* #include "PosixSource.h" */ - +#include "PosixSource.h" #include "Rts.h" + +#include "Signals.h" #include "Schedule.h" #include "RtsUtils.h" -#include "RtsFlags.h" -#include "Timer.h" #include "Itimer.h" -#include "Signals.h" #include "Capability.h" -#include "posix/Select.h" +#include "Select.h" +#include "AwaitEvent.h" + +# ifdef HAVE_SYS_SELECT_H +# include +# endif # ifdef HAVE_SYS_TYPES_H # include @@ -59,12 +61,14 @@ wakeUpSleepingThreads(lnat ticks) StgTSO *tso; rtsBool flag = rtsFalse; - while (sleeping_queue != END_TSO_QUEUE && - (int)(ticks - sleeping_queue->block_info.target) > 0) { + while (sleeping_queue != END_TSO_QUEUE) { tso = sleeping_queue; - sleeping_queue = tso->link; + if (((long)ticks - (long)tso->block_info.target) < 0) { + break; + } + sleeping_queue = tso->_link; tso->why_blocked = NotBlocked; - tso->link = END_TSO_QUEUE; + tso->_link = END_TSO_QUEUE; IF_DEBUG(scheduler,debugBelch("Waking up sleeping thread %lu\n", (unsigned long)tso->id)); // MainCapability: this code is !THREADED_RTS pushOnRunQueue(&MainCapability,tso); @@ -73,6 +77,13 @@ wakeUpSleepingThreads(lnat ticks) return flag; } +static void GNUC3_ATTRIBUTE(__noreturn__) +fdOutOfRange (int fd) +{ + errorBelch("file descriptor %d out of range for select (0--%d).\nRecompile with -threaded to work around this.", fd, (int)FD_SETSIZE); + stg_exit(EXIT_FAILURE); +} + /* Argument 'wait' says whether to wait for I/O to become available, * or whether to just check and return immediately. If there are * other threads ready to run, we normally do the non-waiting variety, @@ -126,7 +137,7 @@ awaitEvent(rtsBool wait) min = 0; } else if (sleeping_queue != END_TSO_QUEUE) { min = (sleeping_queue->block_info.target - ticks) - * TICK_MILLISECS * 1000; + * RtsFlags.MiscFlags.tickInterval * 1000; } else { min = 0x7ffffff; } @@ -138,14 +149,18 @@ awaitEvent(rtsBool wait) FD_ZERO(&wfd); for(tso = blocked_queue_hd; tso != END_TSO_QUEUE; tso = next) { - next = tso->link; + next = tso->_link; + /* On FreeBSD FD_SETSIZE is unsigned. Cast it to signed int + * in order to switch off the 'comparison between signed and + * unsigned error message + */ switch (tso->why_blocked) { case BlockedOnRead: { int fd = tso->block_info.fd; - if (fd >= FD_SETSIZE) { - barf("awaitEvent: descriptor out of range"); + if ((fd >= (int)FD_SETSIZE) || (fd < 0)) { + fdOutOfRange(fd); } maxfd = (fd > maxfd) ? fd : maxfd; FD_SET(fd, &rfd); @@ -155,8 +170,8 @@ awaitEvent(rtsBool wait) case BlockedOnWrite: { int fd = tso->block_info.fd; - if (fd >= FD_SETSIZE) { - barf("awaitEvent: descriptor out of range"); + if ((fd >= (int)FD_SETSIZE) || (fd < 0)) { + fdOutOfRange(fd); } maxfd = (fd > maxfd) ? fd : maxfd; FD_SET(fd, &wfd); @@ -207,7 +222,7 @@ awaitEvent(rtsBool wait) * serviced. */ #if defined(RTS_USER_SIGNALS) - if (signals_pending()) { + if (RtsFlags.MiscFlags.install_signal_handlers && signals_pending()) { startSignalHandlers(&MainCapability); return; /* still hold the lock */ } @@ -238,8 +253,9 @@ awaitEvent(rtsBool wait) prev = NULL; if (select_succeeded || unblock_all) { for(tso = blocked_queue_hd; tso != END_TSO_QUEUE; tso = next) { - next = tso->link; - switch (tso->why_blocked) { + next = tso->_link; + + switch (tso->why_blocked) { case BlockedOnRead: ready = unblock_all || FD_ISSET(tso->block_info.fd, &rfd); break; @@ -253,13 +269,13 @@ awaitEvent(rtsBool wait) if (ready) { IF_DEBUG(scheduler,debugBelch("Waking up blocked thread %lu\n", (unsigned long)tso->id)); tso->why_blocked = NotBlocked; - tso->link = END_TSO_QUEUE; + tso->_link = END_TSO_QUEUE; pushOnRunQueue(&MainCapability,tso); } else { if (prev == NULL) blocked_queue_hd = tso; else - prev->link = tso; + setTSOLink(&MainCapability, prev, tso); prev = tso; } } @@ -267,7 +283,7 @@ awaitEvent(rtsBool wait) if (prev == NULL) blocked_queue_hd = blocked_queue_tl = END_TSO_QUEUE; else { - prev->link = END_TSO_QUEUE; + prev->_link = END_TSO_QUEUE; blocked_queue_tl = prev; } } @@ -277,3 +293,4 @@ awaitEvent(rtsBool wait) } #endif /* THREADED_RTS */ +