Skip to content

timeout: Implemention for windows#13363

Open
nikolalukovic wants to merge 7 commits into
uutils:mainfrom
nikolalukovic:fix/6200
Open

timeout: Implemention for windows#13363
nikolalukovic wants to merge 7 commits into
uutils:mainfrom
nikolalukovic:fix/6200

Conversation

@nikolalukovic

Copy link
Copy Markdown
Contributor

Attempts to fix #6200

@nikolalukovic nikolalukovic changed the title timeout: Implement timeout for windows timeout: Implemention for windows Jul 11, 2026
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/resolution (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/tail/retry (passes in this run but fails in the 'main' branch)
Skip an intermittent issue tests/pr/bounded-memory (was skipped on 'main', now failing)

@Alonely0

Copy link
Copy Markdown
Contributor

how nicely does this play with #13237 ?

@nikolalukovic

nikolalukovic commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

how nicely does this play with #13237 ?

nothing in unix world was changed, just shuffled in diff files, when your PR gets merged I'll just rebase

@Alonely0

Copy link
Copy Markdown
Contributor

Nice then. Quite happy we're getting timeout on Windows land. Let me get this reviewed soon-ish.

@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Unable to generate the performance report

There was an internal error while processing the run's data. We're working on fixing the issue. Feel free to contact us on Discord or at support@codspeed.io if the issue persists.

@Alonely0 Alonely0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks super nice, so lots of thanks for the work! If my other PR lands first, we should be able to enable the benchmarks on *nix as well, and I would hope the rebase/merge isn't too bad; it mostly seems that src/uu/timeout/src/platform/unix.rs would get significantly shrunk (since the logic is moven to uucore), and we'd remove the SIGNALED logic from timeout.rs altogether.

This is a lot of code, so I'll read it with fresh eyes again tomorrow or this week. Also btw, thanks for the new benches!

Comment thread Cargo.toml
]
# "feat_os_windows" == set of utilities which can be built/run on modern windows platforms
feat_os_windows = ["feat_Tier1", "stdbuf"]
feat_os_windows = ["feat_Tier1", "stdbuf", "timeout"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should instead move timeout to tier 1 if we get Windows support.

cc @sylvestre

Comment on lines +336 to +339
/// Overwrites any creation flags set earlier via `CommandExt::creation_flags`.
pub fn configure_process_group(cmd: &mut Command) {
use std::os::windows::process::CommandExt;
cmd.creation_flags(CREATE_NEW_PROCESS_GROUP);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not thrilled about forcing an overwrite, but it seems there's no way around it...

TimedOut,
}

fn cvt(result: BOOL) -> io::Result<()> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would appreciate a small doc comment.

/// polling) shows up as a step change across the arguments.
#[cfg(windows)]
#[divan::bench(args = ["0.001", "0.005", "0.02"])]
fn timer_expiry_latency(bencher: Bencher, duration: &str) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something we should enable on unix after a certain PR lands ;)

/// per-process signalling). Replaced on every spawn so that repeated
/// in-process invocations of `uumain` (benchmarks, fuzzing) never signal a
/// previous run's job.
static JOB: Mutex<Option<Job>> = Mutex::new(None);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this global could be removed by making post_spawn() return an Option<Job> on Windows, then pass it as an argument to platform::send_signal() as well. I know it's not super ideal to have platform-dependent signatures, but I would argue it's much less bug-prone than global state.

/// runs; intentionally lives for the rest of the process.
static WAKE_EVENT: OnceLock<OwnedHandle> = OnceLock::new();
/// POSIX signal number of the last console control event received (0 = none).
static LAST_CTRL_SIGNAL: AtomicI32 = AtomicI32::new(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that LAST_CTRL_SIGNAL is not reset when we handle it, so if you send a signal, timeout thinks it has already sent termination. I can reproduce with a small program that ignores ConsoleCtrlHandler; when ctrl+cing it at leas once, this results in non-termination when it times out.

/// Manual-reset event signalled by the console control handler to wake
/// [`ChildExt::wait_or_timeout`]. Unset until [`enable_ctrl_forwarding`]
/// runs; intentionally lives for the rest of the process.
static WAKE_EVENT: OnceLock<OwnedHandle> = OnceLock::new();

@Alonely0 Alonely0 Jul 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WAKE_EVENT seems to also never be reset at the end, which doesn't matter because we only wait for one program, but I think it would be appreciated by anyone who works in this codebase in the future that it is reset once we're done with it.

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.

timeout (uu_timeout) for Windows

3 participants