Skip to content

Let Stop end a copy that waits on a pipe - #62

Open
thisisgm wants to merge 1 commit into
omacom:mainfrom
thisisgm:stop-read
Open

thisisgm wants to merge 1 commit into
omacom:mainfrom
thisisgm:stop-read

Conversation

@thisisgm

@thisisgm thisisgm commented Nov 11, 2026 •

Copy link
Copy Markdown

The small pull request asked for when #29 was closed: Stop now ends a copy that is waiting on a read that never comes. One commit with its tests. No library, depends or optdepends entry is added.

What you'd notice

Copy a named pipe that nothing writes to, or a folder that holds one, and press Stop. On main the copy stays busy until something writes to the pipe: it waits inside open when the pipe has no writer, and inside read when a writer is there but silent, and Stop is only looked for between pieces. With this change the copy ends within about a tenth of a second and leaves nothing behind.

How

  • The source is opened with O_NONBLOCK, so opening a pipe with no writer returns at once. QFile takes the descriptor over and closes it.
  • Before each read the copy asks poll whether the source has anything, for at most 100 ms (stopCheckMs), and looks for Stop when it has not. A regular file always has its next piece, and a pipe reports its end once its writers are gone, so neither waits there.
  • One kind of regular file refuses an open that will not wait: a file another program holds a write lease on (EWOULDBLOCK). That open is tried again every 100 ms until the lease is given up, with a look for Stop between tries, so such a file is still waited for, and Stop ends that wait too.
  • A read that comes back with EAGAIN goes round again, as EINTR already did.

Regular files take the same road as before, with one poll in front of each megabyte read.

Tests

Three new cases; the suite goes from 196 to 199 tests.

  • fileOpsCancelStopsACopyWaitingOnAPipe copies a pipe twice, once with no writer and once with a writer that never writes. Each time it checks that the copy is still waiting after 300 ms, sets Stop, and expects the copy to end without an error and without a file at the destination. It fails on main, and with either half of the change taken out (an open that waits, or a read that is not asked for first).
  • fileOpsCopyLosesNothingWhenAPipesWriterPauses writes to the pipe, stays silent for longer than a look for Stop takes, writes again and closes, and expects both pieces in the copy.
  • fileOpsCopyWaitsForAFileUnderALease takes a write lease on a file, starts a copy and checks that it waits. Once it gives the lease up and expects the copy whole; once it sets Stop while the lease is held and expects the copy to end with nothing at the destination. It fails when the open is not tried again, and when Stop is not looked for between tries.

The two pipe tests already on main (fileOpsCancelStopsACopyPartway and fileOpsCopyIsNeverOpenToOthersWhileCopying) pass unchanged.

@greptile-apps

greptile-apps Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable defects were found.

Summary

Makes Stop reach copies waiting for a pipe or a leased file.

  • Copying now checks Stop while a pipe or file is waiting.

No actionable issues were found. Tests were inspected, not run. The full PR was reviewed because the previous review and current head have different merge bases with the target commit.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Open source without blocking] --> B{Lease prevents open?}
  B -->|Yes| C{Stop requested?}
  C -->|Yes| D[End without creating output]
  C -->|No| E[Wait 100 ms]
  E --> A
  B -->|No| F[Create output and copy]
  F --> G{Read fallback needed?}
  G -->|Yes| H[Poll for up to 100 ms]
  H --> I{Stop requested?}
  I -->|Yes| J[Remove unfinished output]
  I -->|No| K[Read and write available data]
  K --> H
  G -->|No| L[Continue kernel copy]
Loading

Reviews (4) · Last reviewed commit: "Let Stop end a copy that waits on a pipe" · Reviewed by Greptile

@thisisgm
thisisgm force-pushed the stop-read branch 2 times, most recently from c79bc08 to 1557e86 Compare November 11, 2026 18:21
Copying a pipe nobody writes to waited in open, or in a read, where
Stop was never looked for: the copy stayed busy until something wrote.
The source is now opened without waiting and asked whether it has
anything ten times a second, with Stop read in between. A file under
another program's lease, which refuses such an open, is asked for
again until the lease is given up or Stop is pressed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant