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 | de483b8c49b27e21b098b6831dd0f1c2af7d6fef (patch) | |
tree | c0225b84a6b1e9647c32bb0e8b48a312f51f778f /generic | |
parent | d877359a142f6509076219912e13521decaa926d (diff) | |
parent | 97f7b29ec8d120aa5c156cf7c868feac2895e5fb (diff) | |
download | tcl-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.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) || |