summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorferrieux <ferrieux@users.sourceforge.net>2012-04-28 17:09:58 (GMT)
committerferrieux <ferrieux@users.sourceforge.net>2012-04-28 17:09:58 (GMT)
commitde483b8c49b27e21b098b6831dd0f1c2af7d6fef (patch)
treec0225b84a6b1e9647c32bb0e8b48a312f51f778f /generic
parentd877359a142f6509076219912e13521decaa926d (diff)
parent97f7b29ec8d120aa5c156cf7c868feac2895e5fb (diff)
downloadtcl-de483b8c49b27e21b098b6831dd0f1c2af7d6fef.zip
tcl-de483b8c49b27e21b098b6831dd0f1c2af7d6fef.tar.gz
tcl-de483b8c49b27e21b098b6831dd0f1c2af7d6fef.tar.bz2
IMPLEMENTATION OF TIP#398 : Quickly Exit with Non-Blocking Blocked Channels
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 4ba8cd1..b06c14d 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -396,6 +396,19 @@ TclFinalizeIOSubsystem(void)
Channel *chanPtr = NULL; /* Iterates over open channels. */
ChannelState *statePtr; /* State of channel stack */
int active = 1; /* Flag == 1 while there's still work to do */
+ int doflushnb;
+
+ /* Fetch the pre-TIP#398 compatibility flag */
+ {
+ const char *s;
+ Tcl_DString ds;
+
+ s = TclGetEnv("TCL_FLUSH_NONBLOCKING_ON_EXIT", &ds);
+ doflushnb = ((s != NULL) && strcmp(s, "0"));
+ if (s != NULL) {
+ Tcl_DStringFree(&ds);
+ }
+ }
/*
* Walk all channel state structures known to this thread and close
@@ -414,8 +427,8 @@ TclFinalizeIOSubsystem(void)
statePtr != NULL;
statePtr = statePtr->nextCSPtr) {
chanPtr = statePtr->topChanPtr;
- if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED | CHANNEL_DEAD)
- || GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+ if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED | CHANNEL_DEAD)
+ || (doflushnb && GotFlag(statePtr, BG_FLUSH_SCHEDULED))) {
active = 1;
break;
}
@@ -426,13 +439,21 @@ TclFinalizeIOSubsystem(void)
*/
if (active) {
+
/*
- * Set the channel back into blocking mode to ensure that we wait
- * for all data to flush out.
+ * TIP #398: by default, we no longer set the channel back into
+ * blocking mode. To restore the old blocking behavior, the
+ * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set
+ * and not be "0".
*/
-
- (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
- "-blocking", "on");
+ if (doflushnb) {
+ /* Set the channel back into blocking mode to ensure that we wait
+ * for all data to flush out.
+ */
+
+ (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
+ "-blocking", "on");
+ }
if ((chanPtr == (Channel *) tsdPtr->stdinChannel) ||
(chanPtr == (Channel *) tsdPtr->stdoutChannel) ||