From b4a0257ed31d63ece637c84e20006df85c70cb73 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 21 Aug 2014 23:07:34 +0000 Subject: Test fix for likely cause of reported I/O slowdown. In a DoRead() revision, it came to favor making every effort to fill buffers, in preference to a more sensible goal of favoring avoiding calls out to the driver if there's already enough data in the buffers to satisfy the read operation. Result is many more calls out to recv() than are a good idea. Ought to show up most glaringly when many Tcl_Read() calls asking for small numbers of bytes (compared to buffer size) each, and that matches the reported case. FossilOrigin-Name: 85cd086fd277438a7242118c851cb5ae7cb289f3 --- generic/tclIO.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4452ae9..4f81770 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8855,6 +8855,7 @@ DoRead( /* If there is no full buffer, attempt to create and/or fill one. */ +if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { while (!IsBufferFull(bufPtr)) { int code; @@ -8880,6 +8881,7 @@ DoRead( } assert (bufPtr != NULL); +} bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; -- cgit v0.12 From 91cb8cb97965e3ed55cf370627c72ab983335103 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Aug 2014 13:20:21 +0000 Subject: Same results; simpler logic. FossilOrigin-Name: 5180649ac52bc399db10978a7fde7af931fe5fcb --- generic/tclIO.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4f81770..93ac937 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8853,36 +8853,22 @@ DoRead( break; } - /* If there is no full buffer, attempt to create and/or fill one. */ - -if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { - while (!IsBufferFull(bufPtr)) { - int code; + /* + * If there is not enough data in the buffers to possibly + * complete the read, then go get more. + */ + if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { moreData: - code = GetInput(chanPtr); - bufPtr = statePtr->inQueueHead; - - assert (bufPtr != NULL); - - if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) { - /* Further reads cannot do any more */ - break; - } - - if (code) { + if (GetInput(chanPtr)) { /* Read error */ UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return -1; } - - assert (IsBufferFull(bufPtr)); + bufPtr = statePtr->inQueueHead; } - assert (bufPtr != NULL); -} - bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; -- cgit v0.12