IBM1130: Properly serialize commands and waiting for command completion

As reported in #448
This commit is contained in:
Mark Pizzolato 2017-05-14 06:16:28 -07:00
parent 5917787c53
commit 4df0a9fb1e
3 changed files with 18 additions and 9 deletions

View file

@ -1941,7 +1941,6 @@ static t_stat view_cmd (int32 flag, CONST char *cptr)
sprintf(cmdline, "notepad %s", cptr); sprintf(cmdline, "notepad %s", cptr);
WinExec(cmdline, SW_SHOWNORMAL); WinExec(cmdline, SW_SHOWNORMAL);
Sleep(1000); /* wait a bit to allow notepad to open the file */
#endif #endif
return SCPE_OK; return SCPE_OK;
} }

View file

@ -281,7 +281,7 @@ void break_simulation (t_stat reason); /* let a device halt the sim
char hollerith_to_ascii (uint16 hol); /* for debugging use only */ char hollerith_to_ascii (uint16 hol); /* for debugging use only */
t_bool gdu_active (void); t_bool gdu_active (void);
void remark_cmd (char *remark); void remark_cmd (char *remark);
void stuff_cmd (char *cmd); LONG stuff_cmd (char *cmd);
t_bool stuff_and_wait (char *cmd, int timeout, int delay); t_bool stuff_and_wait (char *cmd, int timeout, int delay);
void update_gui (t_bool force); void update_gui (t_bool force);
void sim_init (void); void sim_init (void);

View file

@ -1475,7 +1475,7 @@ static void tear_printer (void)
return; return;
sprintf(cmd, "view \"%s\"", filename); /* spawn notepad to view it */ sprintf(cmd, "view \"%s\"", filename); /* spawn notepad to view it */
if (! stuff_and_wait(cmd, 3000, 500)) if (! stuff_and_wait(cmd, 3000, 2000))
return; return;
remove(filename); /* delete the file */ remove(filename); /* delete the file */
@ -1522,9 +1522,13 @@ static DWORD iCmdThreadID = 0;
static HANDLE hCmdReadEvent = NULL; static HANDLE hCmdReadEvent = NULL;
static HANDLE hCmdReadyEvent = NULL; static HANDLE hCmdReadyEvent = NULL;
static BOOL scp_reading = FALSE; static BOOL scp_reading = FALSE;
static LONG scp_command = 0;
static char cmdbuffer[256]; static char cmdbuffer[256];
static BOOL read_exiting = FALSE; static BOOL read_exiting = FALSE;
#define SCP_COMMAND InterlockedExchangeAdd(&scp_command, 0L)
#define NEXT_SCP_COMMAND InterlockedIncrement(&scp_command)
/* CmdThread - separate thread to read commands from stdin upon request */ /* CmdThread - separate thread to read commands from stdin upon request */
static DWORD WINAPI CmdThread (LPVOID arg) static DWORD WINAPI CmdThread (LPVOID arg)
@ -1537,14 +1541,17 @@ static DWORD WINAPI CmdThread (LPVOID arg)
continue; /* put breakpoint here to debug */ continue; /* put breakpoint here to debug */
if (read_exiting) if (read_exiting)
break; break;
scp_reading = TRUE; scp_reading = FALSE;
if (ReadFile(hStdIn, cmdbuffer, sizeof(cmdbuffer)-1, &dwBytesRead, NULL)) { if (ReadFile(hStdIn, cmdbuffer, sizeof(cmdbuffer)-1, &dwBytesRead, NULL)) {
cmdbuffer[dwBytesRead] = '\0'; cmdbuffer[dwBytesRead] = '\0';
scp_reading = FALSE; scp_reading = FALSE;
NEXT_SCP_COMMAND;
SetEvent(hCmdReadyEvent); /* notify main thread a line is ready */ SetEvent(hCmdReadyEvent); /* notify main thread a line is ready */
} else { } else {
DWORD dwError = GetLastError(); DWORD dwError = GetLastError();
scp_reading = FALSE; scp_reading = FALSE;
NEXT_SCP_COMMAND;
} }
} }
return 0; return 0;
@ -1598,10 +1605,12 @@ char *read_cmdline (char *ptr, int size, FILE *stream)
/* stuff_cmd - force a command into the read_cmdline output buffer. Called asynchronously by GUI */ /* stuff_cmd - force a command into the read_cmdline output buffer. Called asynchronously by GUI */
void stuff_cmd (char *cmd) LONG stuff_cmd (char *cmd)
{ {
INPUT_RECORD *ip; INPUT_RECORD *ip;
size_t i, j, cmdsize = strlen(cmd); size_t i, j, cmdsize = strlen(cmd);
DWORD dwEventsWritten;
LONG scp_cmd = SCP_COMMAND;
ip = (INPUT_RECORD *)calloc(2+2*cmdsize, sizeof(*ip)); ip = (INPUT_RECORD *)calloc(2+2*cmdsize, sizeof(*ip));
for (i=j=0; i<cmdsize; i++, j++) { for (i=j=0; i<cmdsize; i++, j++) {
@ -1620,8 +1629,9 @@ void stuff_cmd (char *cmd)
j++; j++;
ip[j] = ip[j-1]; ip[j] = ip[j-1];
ip[j].Event.KeyEvent.bKeyDown = FALSE; ip[j].Event.KeyEvent.bKeyDown = FALSE;
WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ip, 2+j, &i); WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ip, 2+j, &dwEventsWritten);
free(ip); free(ip);
return scp_cmd;
} }
/* my_yield - process GUI messages. It's not apparent why stuff_and_wait would block, /* my_yield - process GUI messages. It's not apparent why stuff_and_wait would block,
@ -1646,14 +1656,14 @@ static void my_yield (void)
t_bool stuff_and_wait (char *cmd, int timeout, int delay) t_bool stuff_and_wait (char *cmd, int timeout, int delay)
{ {
stuff_cmd(cmd); LONG scp_cmd = stuff_cmd(cmd);
while (! scp_reading) { while (scp_cmd == SCP_COMMAND) {
if (timeout < 0) if (timeout < 0)
return FALSE; return FALSE;
my_yield(); my_yield();
if (scp_reading) if (scp_cmd != SCP_COMMAND)
break; break;
Sleep(50); Sleep(50);