diff options
author | ferrieux <ferrieux@users.sourceforge.net> | 2012-04-28 17:09:58 (GMT) |
---|---|---|
committer | ferrieux <ferrieux@users.sourceforge.net> | 2012-04-28 17:09:58 (GMT) |
commit | 4afd3525b5e7ea01272b07281dd65833bdb885d7 (patch) | |
tree | c0225b84a6b1e9647c32bb0e8b48a312f51f778f /generic/tclIO.c | |
parent | 28eb0289077aad0052036addef782cce499d0857 (diff) | |
parent | 39e076480d96baa096f628753c88b68eb9d7f601 (diff) | |
download | tcl-4afd3525b5e7ea01272b07281dd65833bdb885d7.zip tcl-4afd3525b5e7ea01272b07281dd65833bdb885d7.tar.gz tcl-4afd3525b5e7ea01272b07281dd65833bdb885d7.tar.bz2 |
IMPLEMENTATION OF TIP#398 : Quickly Exit with Non-Blocking Blocked Channels
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 35 |
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) || |