IBM1130: Properly serialize commands and waiting for command completion
As reported in #448
This commit is contained in:
parent
5917787c53
commit
4df0a9fb1e
3 changed files with 18 additions and 9 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue