Attachment "2921116.patch" to
ticket [2921116fff]
added by
dgp
2010-03-17 05:38:17.
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.172
diff -u -r1.172 tclIO.c
--- generic/tclIO.c 24 Feb 2010 10:45:04 -0000 1.172
+++ generic/tclIO.c 16 Mar 2010 22:36:55 -0000
@@ -4778,6 +4778,13 @@
*/
done:
+ /*
+ * Regenerate the top channel, in case it was changed due to
+ * self-modifying reflected transforms.
+ */
+
+ chanPtr = statePtr->topChanPtr;
+
UpdateInterest(chanPtr);
return copiedTotal;
}
Index: generic/tclIORTrans.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIORTrans.c,v
retrieving revision 1.14
diff -u -r1.14 tclIORTrans.c
--- generic/tclIORTrans.c 5 Mar 2010 22:50:32 -0000 1.14
+++ generic/tclIORTrans.c 16 Mar 2010 22:36:55 -0000
@@ -721,7 +721,7 @@
* structure.
*/
- FreeReflectedTransform(rtPtr);
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
return TCL_ERROR;
#undef CHAN
@@ -931,7 +931,7 @@
}
#endif
- FreeReflectedTransform(rtPtr);
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
return EOK;
}
@@ -1030,7 +1030,7 @@
}
#endif
- FreeReflectedTransform(rtPtr);
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
return (result == TCL_OK) ? EOK : EINVAL;
}
@@ -1072,8 +1072,9 @@
return -1;
}
- gotBytes = 0;
+ Tcl_Preserve(rtPtr);
+ gotBytes = 0;
while (toRead > 0) {
/*
* Loop until the request is satisfied (or no data available from
@@ -1086,7 +1087,7 @@
gotBytes += copied;
if (toRead == 0) {
- return gotBytes;
+ goto stop;
}
/*
@@ -1109,10 +1110,10 @@
int maxRead = -1;
if (!TransformLimit(rtPtr, errorCodePtr, &maxRead)) {
- return -1;
+ goto error;
}
if (maxRead == 0) {
- return gotBytes;
+ goto stop;
} else if (maxRead > 0) {
if (maxRead < toRead) {
toRead = maxRead;
@@ -1121,7 +1122,7 @@
}
if (toRead <= 0) {
- return gotBytes;
+ goto stop;
}
readBytes = Tcl_ReadRaw(rtPtr->parent, buf, toRead);
@@ -1137,11 +1138,11 @@
* we report that instead of the request to re-try.
*/
- return gotBytes;
+ goto stop;
}
*errorCodePtr = Tcl_GetErrno();
- return -1;
+ goto error;
}
if (readBytes == 0) {
@@ -1162,16 +1163,16 @@
if ((gotBytes == 0) && rtPtr->nonblocking) {
*errorCodePtr = EWOULDBLOCK;
- return -1;
+ goto error;
}
- return gotBytes;
+ goto stop;
} else {
/*
* Eof in parent.
*/
if (rtPtr->readIsDrained) {
- return gotBytes;
+ goto stop;
}
/*
@@ -1181,7 +1182,7 @@
if (HAS(rtPtr->methods, METH_DRAIN)) {
if (!TransformDrain(rtPtr, errorCodePtr)) {
- return -1;
+ goto error;
}
}
@@ -1190,7 +1191,7 @@
* The drain delivered nothing.
*/
- return gotBytes;
+ goto stop;
}
/*
@@ -1209,11 +1210,17 @@
*/
if (!TransformRead(rtPtr, errorCodePtr, UCHARP(buf), readBytes)) {
- return -1;
+ goto error;
}
} /* while toRead > 0 */
+ stop:
+ Tcl_Release(rtPtr);
return gotBytes;
+
+ error:
+ gotBytes = -1;
+ goto stop;
}
/*
@@ -1266,6 +1273,8 @@
* we do when explicitly seeking as well.
*/
+ Tcl_Preserve(rtPtr);
+
if ((rtPtr->methods & FLAG(METH_CLEAR))) {
TransformClear(rtPtr);
}
@@ -1277,10 +1286,12 @@
*/
if (!TransformWrite(rtPtr, errorCodePtr, UCHARP(buf), toWrite)) {
+ Tcl_Release(rtPtr);
return -1;
}
*errorCodePtr = EOK;
+ Tcl_Release(rtPtr);
return toWrite;
}
@@ -1331,6 +1342,8 @@
* request down and the result back up unchanged.
*/
+ Tcl_Preserve(rtPtr);
+
if (((seekMode != SEEK_CUR) || (offset != 0))
&& (HAS(rtPtr->methods, METH_CLEAR)
|| HAS(rtPtr->methods, METH_FLUSH))) {
@@ -1353,6 +1366,7 @@
if (HAS(rtPtr->methods, METH_FLUSH)) {
if (!TransformFlush(rtPtr, errorCodePtr, FLUSH_DISCARD)) {
+ Tcl_Release(rtPtr);
return -1;
}
}
@@ -1382,6 +1396,7 @@
}
*errorCodePtr = EOK;
+ Tcl_Release(rtPtr);
return curPos;
}
@@ -1971,7 +1986,7 @@
*/
sr = Tcl_SaveInterpState(rtPtr->interp, 0 /* Dummy */);
- Tcl_Preserve(rtPtr->interp);
+ Tcl_Preserve(rtPtr);
result = Tcl_EvalObjv(rtPtr->interp, cmdc, rtPtr->argv, TCL_EVAL_GLOBAL);
/*
@@ -2016,7 +2031,7 @@
Tcl_IncrRefCount(resObj);
}
Tcl_RestoreInterpState(rtPtr->interp, sr);
- Tcl_Release(rtPtr->interp);
+ Tcl_Release(rtPtr);
/*
* Cleanup of the dynamic parts of the command.
@@ -2531,7 +2546,8 @@
rtmPtr = GetThreadReflectedTransformMap();
hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
Tcl_DeleteHashEntry(hPtr);
- FreeReflectedTransform(rtPtr);
+
+ Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
break;
case ForwardedInput: {