Commit c7fd6356 authored by sof's avatar sof

[project @ 2005-01-21 19:58:51 by sof]

win32 only:
  Tidy up delivery and handling of console events by having the low-level
  console event handler signal the RTS thread blocked waiting for I/O.
parent d9d77353
......@@ -542,7 +542,10 @@ schedule( StgMainThread *mainThread USED_WHEN_RTS_SUPPORTS_THREADS,
// 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
}
......
......@@ -9,6 +9,7 @@
#include "Schedule.h"
#include "RtsUtils.h"
#include "RtsFlags.h"
#include "AsyncIO.h"
extern int stg_InstallConsoleEvent(int action, StgStablePtr *handler);
......@@ -63,6 +64,9 @@ static BOOL WINAPI shutdown_handler(DWORD dwCtrlType)
stg_exit(EXIT_INTERRUPTED);
} else {
interruptStgRts();
/* Cheesy pulsing of an event to wake up a waiting RTS thread, if any */
abandonRequestWait();
resetAbandonRequestWait();
}
return TRUE;
......@@ -197,11 +201,15 @@ static BOOL WINAPI generic_handler(DWORD dwCtrlType)
*/
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;
}
}
......
......@@ -98,10 +98,12 @@ IOWorkerProc(PVOID param)
} 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
......@@ -115,20 +117,34 @@ IOWorkerProc(PVOID param)
* 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; }
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment