summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-07-28 01:42:42 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-07-28 01:42:42 (GMT)
commitab81262de8a6b9f32445810c18f8a509c692384c (patch)
tree2af568fd6575649cf0053f8eb21f8255bf3c4ce3
parent4217a749df3219697b93f646009792e35fe398db (diff)
downloadtcl-ab81262de8a6b9f32445810c18f8a509c692384c.zip
tcl-ab81262de8a6b9f32445810c18f8a509c692384c.tar.gz
tcl-ab81262de8a6b9f32445810c18f8a509c692384c.tar.bz2
Revise MBRead() to be used in both sync and async modes.
-rw-r--r--generic/tclIO.c78
1 files changed, 34 insertions, 44 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 73e1274..d9d37a2 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -186,8 +186,8 @@ static int MoveBytes(CopyState *csPtr);
static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj);
static void MBError(CopyState *csPtr, int mask, int errorCode);
-static void MBRead(ClientData clientData, int mask);
-static int MBWrite(CopyState *csPtr, int mask);
+static int MBRead(CopyState *csPtr);
+static int MBWrite(CopyState *csPtr);
static void MBEvent(ClientData clientData, int mask);
static void CopyEventProc(ClientData clientData, int mask);
@@ -8971,56 +8971,57 @@ MBEvent(
CopyState *csPtr = (CopyState *) clientData;
Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr;
+ ChannelState *inStatePtr = csPtr->readPtr->state;
if (mask & TCL_WRITABLE) {
- Tcl_DeleteChannelHandler(inChan, MBRead, csPtr);
+ Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr);
- switch (MBWrite(csPtr, mask)) {
+ switch (MBWrite(csPtr)) {
case TCL_OK:
MBCallback(csPtr, NULL);
break;
case TCL_CONTINUE:
- Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr);
+ Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr);
break;
}
} else if (mask & TCL_READABLE) {
- (void) MBRead(clientData, mask);
+ if (TCL_OK == MBRead(csPtr)) {
+ /* When at least one full buffer is present, stop reading. */
+ if (IsBufferFull(inStatePtr->inQueueHead)
+ || !Tcl_InputBlocked(inChan)) {
+ Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
+ }
+
+ /* Successful read -- set up to write the bytes we read */
+ Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr);
+ }
}
}
-static void
+static int
MBRead(
- ClientData clientData,
- int mask)
+ CopyState *csPtr)
{
- CopyState *csPtr = (CopyState *) clientData;
ChannelState *inStatePtr = csPtr->readPtr->state;
+ ChannelBuffer *bufPtr = inStatePtr->inQueueHead;
+ int code;
- Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
- Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr;
-
- int code = GetInput(inStatePtr->topChanPtr);
-
- assert (mask & TCL_READABLE);
+ if (bufPtr && BytesLeft(bufPtr) > 0) {
+ return TCL_OK;
+ }
+ code = GetInput(inStatePtr->topChanPtr);
if (code == 0) {
- /* Successful read -- set up to write the bytes we read */
- Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr);
-
- /* When at least one full buffer is present, stop reading. */
- if (IsBufferFull(inStatePtr->inQueueHead)
- || !Tcl_InputBlocked(inChan)) {
- Tcl_DeleteChannelHandler(inChan, MBRead, csPtr);
- }
+ return TCL_OK;
} else {
- MBError(csPtr, mask, code);
+ MBError(csPtr, TCL_READABLE, code);
+ return TCL_ERROR;
}
}
static int
MBWrite(
- CopyState *csPtr,
- int mask)
+ CopyState *csPtr)
{
ChannelState *inStatePtr = csPtr->readPtr->state;
ChannelState *outStatePtr = csPtr->writePtr->state;
@@ -9028,8 +9029,6 @@ MBWrite(
ChannelBuffer *tail = NULL;
int code, inBytes = 0;
- assert (mask & TCL_WRITABLE);
-
/* Count up number of bytes waiting in the input queue */
while (bufPtr) {
inBytes += BytesLeft(bufPtr);
@@ -9075,7 +9074,7 @@ MBWrite(
code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0);
if (code) {
- MBError(csPtr, mask, code);
+ MBError(csPtr, TCL_WRITABLE, code);
return TCL_ERROR;
}
if (csPtr->toRead == 0 || GotFlag(inStatePtr, CHANNEL_EOF)) {
@@ -9088,7 +9087,6 @@ static int
MoveBytes(
CopyState *csPtr) /* State of copy operation. */
{
- ChannelState *inStatePtr = csPtr->readPtr->state;
ChannelState *outStatePtr = csPtr->writePtr->state;
ChannelBuffer *bufPtr = outStatePtr->curOutPtr;
int errorCode;
@@ -9106,25 +9104,17 @@ MoveBytes(
if (csPtr->cmdPtr) {
Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
- Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr);
+ Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr);
return TCL_OK;
}
while (1) {
- ChannelBuffer *bufPtr = inStatePtr->inQueueHead;
int code;
- if (bufPtr == NULL || BytesLeft(bufPtr) == 0) {
-
- /* Nothing in the input queue; Get more input. */
- errorCode = GetInput(inStatePtr->topChanPtr);
- if (errorCode != 0) {
- MBError(csPtr, TCL_READABLE, errorCode);
- return TCL_ERROR;
- }
- bufPtr = inStatePtr->inQueueHead;
+ if (TCL_ERROR == MBRead(csPtr)) {
+ return TCL_ERROR;
}
- code = MBWrite(csPtr, TCL_WRITABLE);
+ code = MBWrite(csPtr);
if (code == TCL_OK) {
Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total));
StopCopy(csPtr);
@@ -9701,7 +9691,7 @@ StopCopy(
if (inChan != outChan) {
Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr);
}
- Tcl_DeleteChannelHandler(inChan, MBRead, csPtr);
+ Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr);
TclDecrRefCount(csPtr->cmdPtr);
}