Ticket UUID: | 3096275 | |||
Title: | Sync fcopy buffers input | |||
Type: | Bug | Version: | None | |
Submitter: | ferrieux | Created on: | 2010-10-27 08:32:25 | |
Subsystem: | 25. Channel System | Assigned To: | dgp | |
Priority: | 9 Immediate | Severity: | Minor | |
Status: | Closed | Last Modified: | 2023-04-03 18:16:19 | |
Resolution: | Fixed | Closed By: | pooryorick | |
Closed on: | 2023-04-03 18:16:19 | |||
Description: |
The following script: fconfigure stdin -translation binary -blocking 0 fconfigure stdout -buffering none -translation binary fcopy stdin stdout when fed by typing lines to stdin, will not output anything until either 4k have been typed or eof, despite the nonblocking mode on stdin. The same using an async fcopy, will work in a more responsive manner: fcopy stdin stdout -command done vwait forever This is a consequence of the following credo, in a comment in TclCopyChannel: /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. If * there is an error, restore the old blocking mode. */ As a consequence, while GetInput happily returns short reads, DoRead insists on filling up its 4k buffer. That is, sync fcopy will never pass short reads on to the output channel. Hence, sync fcopy is not adapted to live streams, while async fcopy is. This it at least surprising for the developer, since the sync/async fcopy decision is rather based on external considerations like "do I need to interleave it with other IO" or "do I need to keep a GUI responsive". The fact that chosing sync implies buffering by 4k is nowhere in the docs. Low prio because it's a Day-1 issue :/ | |||
User Comments: |
pooryorick added on 2023-04-03 18:16:19:
This report dealt with ReadBytes(). See also [9ca87e6286] for the same issue with ReadChars(). ferrieux added on 2011-08-19 03:24:24: Committed. ferrieux added on 2011-07-19 22:42:07: Any hope to review for 8.6.0 ? ferrieux added on 2010-11-05 04:45:05: Also ran tclbench: no slowdown. ferrieux added on 2010-10-28 03:40:32: That can no more occur than before: the new behavior, allowShortReads, is only ever activated when !GotFlag(inStatePtr, CHANNEL_NONBLOCKING) that is, only for a blocking channel, ie in sync fcopy. If you know of another situation yielding a busyloop, please elaborate. andreas_kupries added on 2010-10-28 02:33:32: I can't see anything bad with this, except, maybe, that the sync fcopy go into a tight loop consuming lots of cpu because of a continuous series of 0-char reads until something is typed in. Would like to get a second opinion, assigning to Jeff. ferrieux added on 2010-10-27 17:13:16: File Added - 391352: fcopysync.patch ferrieux added on 2010-10-27 17:12:32: Attached tiny patch fixes the issue, by adding an allowShortReads flag to DoRead, for use only inside CopyData when the input channel is blocking. This allows to exploit the "half-blocking" semantics of pipes and sockets, which can do short reads in blocking mode, thus keeping the overall spirit of sync fcopy (ie don't use the event loop). Checked against the test suite. Again, this removes a day-1, but undocumented, limitation. Raising prio to ask for permission to commit. |
Attachments:
- fcopysync.patch [download] added by ferrieux on 2010-10-27 17:13:15. [details]