From b866f76af7b41ec1764fe4d30df0127cca714658 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 7 May 2017 18:56:48 -0700 Subject: [PATCH] IBM1130: Cleanup GUI command interactions and shutdown activities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleaned up a couple of things here. Specifically: 1) scp_reading is only set when CmdThread is actually reading. 2) Avoid calling ResetEvent(hCmdReadEvent) since it has no effect. 3) Calling ReadFile directly rather than calling read_line which ultimately calls fgets(stdin) and that ultimately calls ReadFile. 4) Added a cleanup mechanism to shutdown the CmdThread and related open handles to Events and Thread when the program exits. Remaining potential problems: 1) A user might have type a partial command (scp_reading) but not completed it by hitting Enter, and then they perform some GUI interaction which does other things. Some strange output will be produced on top of the partially entered command line. 2) Whether or not a complete command has been entered, the original CmdThread will have a read posted on stdin throughout any activity initiated by GUI activities. It is not clear that the simulator’s console will coherently be able to change the console’s mode from the line oriented mode that SCP uses to the character oriented mode used while instructions are executing with read pending on the input side. --- Ibm1130/ibm1130_gui.c | 57 +++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/Ibm1130/ibm1130_gui.c b/Ibm1130/ibm1130_gui.c index 7b9363be..d24ab16d 100644 --- a/Ibm1130/ibm1130_gui.c +++ b/Ibm1130/ibm1130_gui.c @@ -1523,21 +1523,54 @@ static HANDLE hCmdReadEvent = NULL; static HANDLE hCmdReadyEvent = NULL; static BOOL scp_stuffed = FALSE, scp_reading = FALSE; static char cmdbuffer[256]; +static BOOL read_exiting = FALSE; /* CmdThread - separate thread to read commands from stdin upon request */ static DWORD WINAPI CmdThread (LPVOID arg) { +HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); +DWORD dwBytesRead; + for (;;) { - WaitForSingleObject(hCmdReadEvent, INFINITE); /* wait for request */ - read_line(cmdbuffer, sizeof(cmdbuffer), stdin); /* read one line */ - scp_stuffed = FALSE; /* say how we got it */ - scp_reading = FALSE; - SetEvent(hCmdReadyEvent); /* notify main thread a line is ready */ + if (WAIT_TIMEOUT == WaitForSingleObject(hCmdReadEvent, 2000)) /* wait for request */ + continue; /* put breakpoint here to debug */ + if (read_exiting) + break; + scp_reading = TRUE; + if (ReadFile(hStdIn, cmdbuffer, sizeof(cmdbuffer)-1, &dwBytesRead, NULL)) { + cmdbuffer[dwBytesRead] = '\0'; + scp_stuffed = FALSE; /* say how we got it */ + scp_reading = FALSE; + SetEvent(hCmdReadyEvent); /* notify main thread a line is ready */ + } else { + DWORD dwError = GetLastError(); + scp_reading = FALSE; + } } return 0; } +static void read_atexit (void) +{ + typedef BOOL (WINAPI *_func)(HANDLE, LPOVERLAPPED); + _func pCancelIoEx; + + read_exiting = TRUE; + pCancelIoEx = (_func)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx"); + if (pCancelIoEx) { + pCancelIoEx(GetStdHandle(STD_INPUT_HANDLE), NULL); + SetEvent(hCmdReadEvent); /* wake read thread */ + WaitForSingleObject(hCmdThread, INFINITE); + } + CloseHandle(hCmdReadyEvent); + hCmdReadyEvent = NULL; + CloseHandle(hCmdReadEvent); + hCmdReadEvent = NULL; + CloseHandle(hCmdThread); + hCmdThread = NULL; +} + char *read_cmdline (char *ptr, int size, FILE *stream) { char *cptr; @@ -1551,10 +1584,9 @@ char *read_cmdline (char *ptr, int size, FILE *stream) /* start up the command thread */ if ((hCmdThread = CreateThread(NULL, 0, CmdThread, NULL, 0, &iCmdThreadID)) == NULL) scp_panic("Unable to create command line reading thread"); + atexit(read_atexit); } - scp_reading = TRUE; - SetEvent(hCmdReadEvent); /* let read thread get one line */ WaitForSingleObject(hCmdReadyEvent, INFINITE); /* wait for read thread or GUI to respond */ strncpy(ptr, cmdbuffer, MIN(size, sizeof(cmdbuffer))); /* copy line to caller's buffer */ @@ -1564,6 +1596,7 @@ char *read_cmdline (char *ptr, int size, FILE *stream) if (scp_stuffed) { /* stuffed command needs to be echoed */ sim_printf("%s\n", cptr); + scp_stuffed = FALSE; } return cptr; @@ -1575,8 +1608,6 @@ void stuff_cmd (char *cmd) { strcpy(cmdbuffer, cmd); /* save the string */ scp_stuffed = TRUE; /* note where it came from */ - scp_reading = FALSE; - ResetEvent(hCmdReadEvent); /* clear read request event */ SetEvent(hCmdReadyEvent); /* notify main thread a line is ready */ } @@ -1602,8 +1633,6 @@ static void my_yield (void) t_bool stuff_and_wait (char *cmd, int timeout, int delay) { - scp_reading = FALSE; - stuff_cmd(cmd); while (! scp_reading) { @@ -1635,10 +1664,8 @@ t_bool stuff_and_wait (char *cmd, int timeout, int delay) void remark_cmd (char *remark) { - if (scp_reading) { - putchar('\n'); - if (sim_log) putc('\n', sim_log); - } + if (scp_reading) + sim_printf("\n"); sim_printf("%s\n", remark);