// ToDo: add deadlock detection in GUM (similar to SMP) -- HWL
#endif
-#if defined(RTS_SUPPORTS_THREADS)
+#if defined(RTS_SUPPORTS_THREADS) || defined(mingw32_TARGET_OS)
+ /* win32: might be back here due to awaitEvent() being abandoned
+ * as a result of a console event having been delivered.
+ */
if ( EMPTY_RUN_QUEUE() ) {
continue; // nothing to do
}
#include "Schedule.h"
#include "RtsUtils.h"
#include "RtsFlags.h"
+#include "AsyncIO.h"
extern int stg_InstallConsoleEvent(int action, StgStablePtr *handler);
stg_exit(EXIT_INTERRUPTED);
} else {
interruptStgRts();
+ /* Cheesy pulsing of an event to wake up a waiting RTS thread, if any */
+ abandonRequestWait();
+ resetAbandonRequestWait();
}
return TRUE;
*/
return FALSE;
default:
+ if (!deliver_event) return TRUE;
+
if ( stg_pending_events < N_PENDING_EVENTS ) {
stg_pending_buf[stg_pending_events] = dwCtrlType;
stg_pending_events++;
}
- context_switch = 1;
+ /* Cheesy pulsing of an event to wake up a waiting RTS thread, if any */
+ abandonRequestWait();
+ resetAbandonRequestWait();
return TRUE;
}
}
} else {
DWORD dw;
+ while (1) {
/* Do the read(), with extra-special handling for Ctrl+C */
len = read(work->workData.ioData.fd,
work->workData.ioData.buf,
work->workData.ioData.len);
+ dw = GetLastError();
if ( len == 0 && work->workData.ioData.len != 0 ) {
/* Given the following scenario:
* - a console handler has been registered that handles Ctrl+C
* and the above read() (i.e., under the hood, a ReadFile() op) returns
* 0, with the error set to ERROR_OPERATION_ABORTED. We don't
* want to percolate this non-EOF condition too far back up, but ignore
- * it. However, we do want to give the RTS an opportunity to deliver the
- * console event.
- *
- * Hence, we set 'errorCode' to (-2), which we then look out for in
- * GHC.Conc.asyncRead.
+ * it.
+ *
+ * However, we do want to give the RTS an opportunity to deliver the
+ * console event. Take care of this in the low-level console handler
+ * in ConsoleHandler.c which wakes up the RTS thread that's blocked
+ * waiting for I/O results from this worker (and possibly others).
+ * It won't see any I/O, but notices and dispatches the queued up
+ * signals/console events while in the Scheduler.
+ *
+ * The original, and way hackier scheme, was to have the worker
+ * return a special return code representing aborted-due-to-ctrl-C-on-stdin,
+ * which GHC.Conc.asyncRead would look out for and retry the I/O
+ * call if encountered.
*/
- dw = GetLastError();
if ( dw == ERROR_OPERATION_ABORTED ) {
/* Only do the retry when dealing with the standard input handle. */
HANDLE h = (HANDLE)GetStdHandle(STD_INPUT_HANDLE);
if ( _get_osfhandle(work->workData.ioData.fd) == (long)h ) {
- errCode = (DWORD)-2;
+ Sleep(0);
+ } else {
+ break;
}
+ } else {
+ break;
}
+ } else {
+ break;
+ }
}
if (len == -1) { errCode = errno; }
}