Conversation
A transfer's only bound was the per-byte timeout, so a peer trickling one byte just inside it held loop() -- and with it the C64 menu -- for as long as it liked: 65535 x 500 mS for a WriteC64Mem, and longer for a file. Receiving and sending a file and WriteC64Mem now stop at TransferCeilingmS(len), a floor plus the length at a rate well under what each channel really does, and answer FailToken with how far they got. After a failed receive, DrainCmdChannel discards what the peer is still sending, bounded itself, so the rest of the payload is not read as the next command. And the flushes on these paths go through FlushCmdChannel, which does not block: EthernetClient::flush() and the USB host serial's flush wait with no deadline for a peer to acknowledge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #37 and independent of the extension work. Based on
main.The problem. A transfer's only bound was the per-byte timeout. A peer trickling one byte just inside it held
loop(), and with it the C64 menu, for as long as it liked. That is 65535 × 500 mS (9.1 hours) for aWriteC64Mem, and longer for a file.The fix.
WriteC64Memnow stop atTransferCeilingmS(len). That is a floor, plus the length at a rate well under what each channel really does. They answerFailTokenwith how far they got. The deadline is per channel because a single floor would fail real uploads:USBHostSerialat 115200 8N1 moves 11.52 bytes/mS at the wire.DrainCmdChanneldiscards what the peer is still sending, and is itself bounded. Without it, the rest of the payload was read as the next command. A side effect: a command sent within about a second of a per-byte timeout is drained with the rest.FlushCmdChannel, which does not block.EthernetClient::flush()and the USB host serial'sflush()wait for the peer to acknowledge, with no deadline.Merging alongside the others
FlushCmdChannel, at the same spot. Git merges the two into one definition (git merge-tree).WriteC64Memcommand. That merges cleanly too.Measured on this branch
FailTokenwithToo slow, 18 of 1000 bytes, and it answered a version request afterwards. The 18 bytes stay on the card as a partial file, as a per-byte timeout leaves one today.Not measured: the same trickle against
mainas a control, and the Ethernet and USB-host channels.