summaryrefslogtreecommitdiffstats
path: root/win/tclWinConsole.c
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2022-07-05 15:54:00 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2022-07-05 15:54:00 (GMT)
commiteb33dbb186b524be57dd9b4c2ebb9b703cb5080a (patch)
treebecd3f8375a439498e9dfc6f96a91d1c10042b08 /win/tclWinConsole.c
parentdda0e7f5f62db678465c31383298f07ab102a2d1 (diff)
downloadtcl-eb33dbb186b524be57dd9b4c2ebb9b703cb5080a.zip
tcl-eb33dbb186b524be57dd9b4c2ebb9b703cb5080a.tar.gz
tcl-eb33dbb186b524be57dd9b4c2ebb9b703cb5080a.tar.bz2
Fix channel close on thread exit if other threads exist. Add winconsole tests.
Diffstat (limited to 'win/tclWinConsole.c')
-rw-r--r--win/tclWinConsole.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c
index 4f67b64..2e60c91 100644
--- a/win/tclWinConsole.c
+++ b/win/tclWinConsole.c
@@ -1014,11 +1014,20 @@ ConsoleCloseProc(
*/
AcquireSRWLockShared(&handleInfoPtr->lock);
- handleInfoPtr->numRefs -= 1; /* Remove reference from this channel */
- handleInfoPtr->console = INVALID_HANDLE_VALUE;
+ if (closeHandle) {
+ handleInfoPtr->console = INVALID_HANDLE_VALUE;
+ }
/* Break the thread out of blocking console i/o */
- CancelSynchronousIo(handleInfoPtr->consoleThread);
+ handleInfoPtr->numRefs -= 1; /* Remove reference from this channel */
+ if (handleInfoPtr->numRefs == 1) {
+ /*
+ * Abort the i/o if no other threads are listening on it.
+ * Note without this check, an input line will be skipped on
+ * the cancel.
+ */
+ CancelSynchronousIo(handleInfoPtr->consoleThread);
+ }
/*
* Wake up the console handling thread. Note we do not explicitly
@@ -1113,7 +1122,11 @@ ConsoleInputProc(
*/
if (numRead != 0) {
/* If console thread was blocked, awaken it */
- // XXX WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ if (chanInfoPtr->flags & CONSOLE_ASYNC) {
+ /* Async channels always want read ahead */
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ }
break;
}
/*
@@ -1167,6 +1180,11 @@ ConsoleInputProc(
}
/* Lock is reacquired, loop back to try again */
}
+ if (chanInfoPtr->flags & CONSOLE_ASYNC) {
+ /* Async channels always want read ahead */
+ handleInfoPtr->flags |= CONSOLE_DATA_AWAITED;
+ WakeConditionVariable(&handleInfoPtr->consoleThreadCV);
+ }
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
return numRead;
@@ -2186,12 +2204,13 @@ ConsoleSetOptionProc(
return TCL_ERROR;
}
if (Tcl_UtfNcasecmp(value, "NORMAL", vlen) == 0) {
- mode |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT;
+ mode |=
+ ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
} else if (Tcl_UtfNcasecmp(value, "PASSWORD", vlen) == 0) {
- mode |= ENABLE_LINE_INPUT;
+ mode |= ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT;
mode &= ~ENABLE_ECHO_INPUT;
} else if (Tcl_UtfNcasecmp(value, "RAW", vlen) == 0) {
- mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
+ mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
} else if (Tcl_UtfNcasecmp(value, "RESET", vlen) == 0) {
/*
* Reset to the initial mode, whatever that is.