summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2008-04-07 22:17:36 (GMT)
committerandreas_kupries <akupries@shaw.ca>2008-04-07 22:17:36 (GMT)
commit56497ff7346fa776215fc25fd154ee60d5422e2b (patch)
tree153cea45c09d973240fba5c1b70cd4c09cb693b0 /generic
parent2a9d0c7d0ca876dc97db9373e820c520ad293b7b (diff)
downloadtcl-56497ff7346fa776215fc25fd154ee60d5422e2b.zip
tcl-56497ff7346fa776215fc25fd154ee60d5422e2b.tar.gz
tcl-56497ff7346fa776215fc25fd154ee60d5422e2b.tar.bz2
* tests/io.test (io-53.10): Testcase for bi-directionaly fcopy.
* generic/tclIO.c: Additional changes to data structures for fcopy * generic/tclIO.h: and channels to perform proper cleanup in case of a channel having two background copy operations running as is now possible.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c66
-rw-r--r--generic/tclIO.h5
2 files changed, 42 insertions, 29 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 739b644..3f79021 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.61.2.26 2008/04/07 19:40:58 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.61.2.27 2008/04/07 22:17:37 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -157,9 +157,8 @@ static int WriteChars _ANSI_ARGS_((Channel *chanPtr,
CONST char *src, int srcLen));
#define BUSY_STATE(st,fl) \
- ((st)->csPtr && \
- ( (((fl)&TCL_READABLE)&&((st)->csPtr->readPtr ==(st)->topChanPtr)) || \
- (((fl)&TCL_WRITABLE)&&((st)->csPtr->writePtr==(st)->topChanPtr))))
+ ((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
+ (((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
/*
*---------------------------------------------------------------------------
@@ -1218,7 +1217,8 @@ Tcl_CreateChannel(typePtr, chanName, instanceData, mask)
statePtr->scriptRecordPtr = (EventScriptRecord *) NULL;
statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
statePtr->timer = NULL;
- statePtr->csPtr = NULL;
+ statePtr->csPtrR = NULL;
+ statePtr->csPtrW = NULL;
statePtr->outputStage = NULL;
if ((statePtr->encoding != NULL) && (statePtr->flags & TCL_WRITABLE)) {
@@ -1374,13 +1374,18 @@ Tcl_StackChannel(interp, typePtr, instanceData, mask, prevChan)
*/
if ((mask & TCL_WRITABLE) != 0) {
- CopyState *csPtr;
+ CopyState *csPtrR;
+ CopyState *csPtrW;
- csPtr = statePtr->csPtr;
- statePtr->csPtr = (CopyState*) NULL;
+ csPtrR = statePtr->csPtrR;
+ statePtr->csPtrR = (CopyState*) NULL;
+
+ csPtrW = statePtr->csPtrW;
+ statePtr->csPtrW = (CopyState*) NULL;
if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) {
- statePtr->csPtr = csPtr;
+ statePtr->csPtrR = csPtrR;
+ statePtr->csPtrW = csPtrW;
if (interp) {
Tcl_AppendResult(interp, "could not flush channel \"",
Tcl_GetChannelName(prevChan), "\"", (char *) NULL);
@@ -1388,7 +1393,8 @@ Tcl_StackChannel(interp, typePtr, instanceData, mask, prevChan)
return (Tcl_Channel) NULL;
}
- statePtr->csPtr = csPtr;
+ statePtr->csPtrR = csPtrR;
+ statePtr->csPtrW = csPtrW;
}
/*
* Discard any input in the buffers. They are not yet read by the
@@ -1503,13 +1509,18 @@ Tcl_UnstackChannel (interp, chan)
*/
if (statePtr->flags & TCL_WRITABLE) {
- CopyState* csPtr;
+ CopyState *csPtrR;
+ CopyState *csPtrW;
+
+ csPtrR = statePtr->csPtrR;
+ statePtr->csPtrR = (CopyState*) NULL;
- csPtr = statePtr->csPtr;
- statePtr->csPtr = (CopyState*) NULL;
+ csPtrW = statePtr->csPtrW;
+ statePtr->csPtrW = (CopyState*) NULL;
if (Tcl_Flush((Tcl_Channel) chanPtr) != TCL_OK) {
- statePtr->csPtr = csPtr;
+ statePtr->csPtrR = csPtrR;
+ statePtr->csPtrW = csPtrW;
if (interp) {
Tcl_AppendResult(interp, "could not flush channel \"",
Tcl_GetChannelName((Tcl_Channel) chanPtr), "\"",
@@ -1518,7 +1529,8 @@ Tcl_UnstackChannel (interp, chan)
return TCL_ERROR;
}
- statePtr->csPtr = csPtr;
+ statePtr->csPtrR = csPtrR;
+ statePtr->csPtrW = csPtrW;
}
/*
@@ -2739,7 +2751,8 @@ Tcl_ClearChannelHandlers (channel)
* Cancel any pending copy operation.
*/
- StopCopy(statePtr->csPtr);
+ StopCopy(statePtr->csPtrR);
+ StopCopy(statePtr->csPtrW);
/*
* Must set the interest mask now to 0, otherwise infinite loops
@@ -6319,12 +6332,10 @@ Tcl_GetChannelOption(interp, chan, optionName, dsPtr)
* If we are in the middle of a background copy, use the saved flags.
*/
- if (statePtr->csPtr) {
- if (chanPtr == statePtr->csPtr->readPtr) {
- flags = statePtr->csPtr->readFlags;
- } else {
- flags = statePtr->csPtr->writeFlags;
- }
+ if (statePtr->csPtrR) {
+ flags = statePtr->csPtrR->readFlags;
+ } else if (statePtr->csPtrW) {
+ flags = statePtr->csPtrW->writeFlags;
} else {
flags = statePtr->flags;
}
@@ -6534,7 +6545,7 @@ Tcl_SetChannelOption(interp, chan, optionName, newValue)
* If the channel is in the middle of a background copy, fail.
*/
- if (statePtr->csPtr) {
+ if (statePtr->csPtrR || statePtr->csPtrW) {
if (interp) {
Tcl_AppendResult(interp,
"unable to set channel options: background copy in progress",
@@ -7757,8 +7768,9 @@ TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr)
Tcl_IncrRefCount(cmdPtr);
}
csPtr->cmdPtr = cmdPtr;
- inStatePtr->csPtr = csPtr;
- outStatePtr->csPtr = csPtr;
+
+ inStatePtr->csPtrR = csPtr;
+ outStatePtr->csPtrW = csPtr;
/*
* Start copying data between the channels.
@@ -8698,8 +8710,8 @@ StopCopy(csPtr)
}
Tcl_DecrRefCount(csPtr->cmdPtr);
}
- inStatePtr->csPtr = NULL;
- outStatePtr->csPtr = NULL;
+ inStatePtr->csPtrR = NULL;
+ outStatePtr->csPtrW = NULL;
ckfree((char*) csPtr);
}
diff --git a/generic/tclIO.h b/generic/tclIO.h
index ea3c6e4..4564f32 100644
--- a/generic/tclIO.h
+++ b/generic/tclIO.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.h,v 1.5.4.2 2004/07/15 20:46:19 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclIO.h,v 1.5.4.3 2008/04/07 22:17:37 andreas_kupries Exp $
*/
/*
@@ -225,7 +225,8 @@ typedef struct ChannelState {
int bufSize; /* What size buffers to allocate? */
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
- CopyState *csPtr; /* State of background copy, or NULL. */
+ CopyState *csPtrR; /* State of background copy for which channel is input, or NULL. */
+ CopyState *csPtrW; /* State of background copy for which channel is output, or NULL. */
Channel *topChanPtr; /* Refers to topmost channel in a stack.
* Never NULL. */
Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.