Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1019,14 +1019,7 @@ green-tests: green-smoke green-threadlocal green-pingpong green-producer-consume
# a case that legitimately differs under green (nondeterministic scheduling
# order that its expected output happens to encode) belongs in
# GREEN_CORPUS_EXCLUDE with a reason, not in a loosened compare.
# test_process_ctx: under a single green worker (PITH_GREEN_WORKERS=1), a
# deadline-limited read_exact on a subprocess pipe reports the read failed but
# classifies the error as unexpected-eof rather than deadline-exceeded — its
# spawned read-worker returns empty on would-block instead of yielding until
# data or the deadline. correct at the default worker count and os-thread; a
# narrow single-worker green bug tracked separately. (see the read_exact ctx
# path in std/io.pith.)
GREEN_CORPUS_EXCLUDE := test_process_ctx
GREEN_CORPUS_EXCLUDE :=
GREEN_CORPUS_EXPECTED := $(filter-out $(addprefix tests/expected/,$(addsuffix .txt,$(GREEN_CORPUS_EXCLUDE))),$(REGRESSION_EXPECTED))

verify-green-corpus: build verify-green-corpus-only
Expand Down
28 changes: 28 additions & 0 deletions std/io.pith
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,13 @@ fn process_stdout_read_ctx(reader: ProcessStdout, ctx: Context, max_bytes: Int)
fail context_blocking_error(ctx)
time.delay(1)
read := await task
# the worker can finish the same instant the deadline fires: `is_done()`
# then wins the poll before the cancel is seen, so a read that came back
# empty only because it would have blocked is about to be mistaken for a
# clean end-of-stream. when the context is cancelled and nothing was read,
# it is the deadline, not eof.
if ctx.is_cancelled() and (read.is_err or read.ok.len() == 0):
fail context_blocking_error(ctx)
if read.is_err:
fail blocking_failed(read.err)
return read.ok
Expand All @@ -1298,6 +1305,13 @@ fn process_stderr_read_ctx(reader: ProcessStderr, ctx: Context, max_bytes: Int)
fail context_blocking_error(ctx)
time.delay(1)
read := await task
# the worker can finish the same instant the deadline fires: `is_done()`
# then wins the poll before the cancel is seen, so a read that came back
# empty only because it would have blocked is about to be mistaken for a
# clean end-of-stream. when the context is cancelled and nothing was read,
# it is the deadline, not eof.
if ctx.is_cancelled() and (read.is_err or read.ok.len() == 0):
fail context_blocking_error(ctx)
if read.is_err:
fail blocking_failed(read.err)
return read.ok
Expand Down Expand Up @@ -1538,6 +1552,13 @@ fn process_stdout_read_bytes_ctx(reader: ProcessStdout, ctx: Context, max_bytes:
fail context_blocking_error(ctx)
time.delay(1)
read := await task
# the worker can finish the same instant the deadline fires: `is_done()`
# then wins the poll before the cancel is seen, so a read that came back
# empty only because it would have blocked is about to be mistaken for a
# clean end-of-stream. when the context is cancelled and nothing was read,
# it is the deadline, not eof.
if ctx.is_cancelled() and (read.is_err or read.ok.len() == 0):
fail context_blocking_error(ctx)
if read.is_err:
fail blocking_failed(read.err)
return read.ok
Expand All @@ -1564,6 +1585,13 @@ fn process_stderr_read_bytes_ctx(reader: ProcessStderr, ctx: Context, max_bytes:
fail context_blocking_error(ctx)
time.delay(1)
read := await task
# the worker can finish the same instant the deadline fires: `is_done()`
# then wins the poll before the cancel is seen, so a read that came back
# empty only because it would have blocked is about to be mistaken for a
# clean end-of-stream. when the context is cancelled and nothing was read,
# it is the deadline, not eof.
if ctx.is_cancelled() and (read.is_err or read.ok.len() == 0):
fail context_blocking_error(ctx)
if read.is_err:
fail blocking_failed(read.err)
return read.ok
Expand Down
Loading