*
*/
#include "Rts.h"
-#include "Storage.h"
#include <windows.h>
#include "ConsoleHandler.h"
#include "SchedAPI.h"
#include "RtsUtils.h"
#include "RtsFlags.h"
#include "AsyncIO.h"
-#include "Stable.h"
#include "RtsSignals.h"
extern int stg_InstallConsoleEvent(int action, StgStablePtr *handler);
static BOOL WINAPI generic_handler(DWORD dwCtrlType);
static rtsBool deliver_event = rtsTrue;
-static StgInt console_handler = STG_SIG_DFL;
+StgInt console_handler = STG_SIG_DFL;
+
+#if !defined(THREADED_RTS)
static HANDLE hConsoleEvent = INVALID_HANDLE_VALUE;
StgInt stg_pending_events = 0; /* number of undelivered events */
DWORD stg_pending_buf[N_PENDING_EVENTS]; /* their associated event numbers. */
+#endif
+
/*
* Function: initUserSignals()
*
void
initUserSignals(void)
{
- stg_pending_events = 0;
console_handler = STG_SIG_DFL;
+#if !defined (THREADED_RTS)
+ stg_pending_events = 0;
if (hConsoleEvent == INVALID_HANDLE_VALUE) {
hConsoleEvent =
CreateEvent ( NULL, /* default security attributes */
FALSE, /* initially non-signalled */
NULL); /* no name */
}
+#endif
return;
}
+void
+freeSignalHandlers(void) {
+ /* Do nothing */
+}
+
/* Seems to be a bit of an orphan...where used? */
void
finiUserSignals(void)
{
+#if !defined (THREADED_RTS)
if (hConsoleEvent != INVALID_HANDLE_VALUE) {
CloseHandle(hConsoleEvent);
}
+#endif
}
/*
stg_exit(EXIT_INTERRUPTED);
} else {
interruptStgRts();
- /* Cheesy pulsing of an event to wake up a waiting RTS thread, if any */
- abandonRequestWait();
- resetAbandonRequestWait();
}
return TRUE;
}
+#if !defined (THREADED_RTS)
/*
* Function: startSignalHandlers()
*
RELEASE_LOCK(&sched_mutex);
unblockUserSignals();
}
+#endif /* !THREADED_RTS */
/*
* Function: markSignalHandlers()
*/
static BOOL WINAPI generic_handler(DWORD dwCtrlType)
{
- ACQUIRE_LOCK(&sched_mutex);
-
/* Ultra-simple -- up the counter + signal a switch. */
switch(dwCtrlType) {
case CTRL_CLOSE_EVENT:
default:
if (!deliver_event) return TRUE;
+#if defined(THREADED_RTS)
+ sendIOManagerEvent((StgWord8) ((dwCtrlType<<1) | 1));
+#else
if ( stg_pending_events < N_PENDING_EVENTS ) {
stg_pending_buf[stg_pending_events] = dwCtrlType;
stg_pending_events++;
}
- /* Cheesy pulsing of an event to wake up a waiting RTS thread, if any */
- abandonRequestWait();
- resetAbandonRequestWait();
+#endif
return TRUE;
}
-
- RELEASE_LOCK(&sched_mutex);
}
}
break;
case STG_SIG_HAN:
+#ifdef THREADED_RTS
+ // handler is stored in an MVar in the threaded RTS
+ console_handler = STG_SIG_HAN;
+#else
console_handler = (StgInt)*handler;
- if ( previous_hdlr < 0 ) {
+#endif
+ if (previous_hdlr < 0 || previous_hdlr == STG_SIG_HAN) {
/* Only install generic_handler() once */
if ( !SetConsoleCtrlHandler(generic_handler, TRUE) ) {
errorBelch("warning: unable to install console event handler");
}
if (previous_hdlr == STG_SIG_DFL ||
- previous_hdlr == STG_SIG_IGN) {
+ previous_hdlr == STG_SIG_IGN ||
+ previous_hdlr == STG_SIG_HAN) {
return previous_hdlr;
} else {
- *handler = (StgStablePtr)previous_hdlr;
+ if (handler != NULL) {
+ *handler = (StgStablePtr)previous_hdlr;
+ }
return STG_SIG_HAN;
}
}
*
*/
void
-rts_ConsoleHandlerDone(int ev)
+rts_ConsoleHandlerDone (int ev USED_IF_NOT_THREADS)
{
+#if !defined(THREADED_RTS)
if ( (DWORD)ev == CTRL_BREAK_EVENT ||
(DWORD)ev == CTRL_C_EVENT ) {
/* only these two cause stdin system calls to abort.. */
SetEvent(hConsoleEvent); /* event is manual-reset */
Sleep(0); /* yield */
ResetEvent(hConsoleEvent); /* turn it back off again */
+ // SDM: yeuch, this can't possibly work reliably.
+ // I'm not having it in THREADED_RTS.
}
+#endif
}
+#if !defined(THREADED_RTS)
/*
* Function: rts_waitConsoleHandlerCompletion()
*
*/
return (WaitForSingleObject(hConsoleEvent, INFINITE) == WAIT_OBJECT_0);
}
+#endif