Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(runtime/signal): implement SIGINT and SIGBREAK for windows #14694

Merged
merged 25 commits into from
Jun 13, 2022
Merged

feat(runtime/signal): implement SIGINT and SIGBREAK for windows #14694

merged 25 commits into from
Jun 13, 2022

Conversation

GJZwiers
Copy link
Contributor

@GJZwiers GJZwiers commented May 21, 2022

Revival of #10258. Adds support for SIGINT and SIGBREAK signals on Windows platform.

Lots of credits to @juzi5201314 for the initial efforts.

Closes #10236.

@GJZwiers GJZwiers marked this pull request as ready for review May 23, 2022 17:29
@bartlomieju
Copy link
Member

An update to std/node/ is needed to resolve a couple of failing tests.

@GJZwiers can you handle that first?

@GJZwiers
Copy link
Contributor Author

@bartlomieju The type errors for sigbreak are gone now, but other tests are failing. Maybe that's because of the std update?
https://github.com/denoland/deno/runs/6597255925?check_suite_focus=true#step:32:1160

@bartlomieju
Copy link
Member

@bartlomieju The type errors for sigbreak are gone now, but other tests are failing. Maybe that's because of the std update? https://github.com/denoland/deno/runs/6597255925?check_suite_focus=true#step:32:1160

Yes, that's true. I'll make sure to upgrade deno_std in a separate PR to unblock you.

@bartlomieju
Copy link
Member

Opened #14722

@bartlomieju
Copy link
Member

@GJZwiers after merging with main you should be good to go

"SIGBREAK" => CTRL_BREAK_EVENT,
_ => unreachable!(),
},
pid as u32,
Copy link
Member

Choose a reason for hiding this comment

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

@GJZwiers Did you check that processes actually receive the CTR_C_EVENT?

According to MSDN (which is often wildly inaccurate, but still) you can only send it to CTR_C_EVENT to all processes in the terminal.
From: https://docs.microsoft.com/en-us/windows/console/generateconsolectrlevent

This signal cannot be limited to a specific process group. If dwProcessGroupId is nonzero, this function will succeed, but the CTRL+C signal will not be received by processes within the specified process group.

Copy link
Contributor Author

@GJZwiers GJZwiers May 31, 2022

Choose a reason for hiding this comment

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

I checked some of the examples on https://deno.land/manual/examples/os_signals and they are working on windows with the current changes.

Copy link
Member

@dsherret dsherret Jun 14, 2022

Choose a reason for hiding this comment

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

I was trying to write some tests for SIGINT and SIGBREAK in this PR and ran into this issue where sending a SIGINT to the child process also kills the parent in the terminal. It seems very unexpected and different than other OSes.

Copy link
Contributor

Choose a reason for hiding this comment

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

For WinOS, new "child" processes, created from a console process using CreateProcess(), all share the same console (unless created with CREATE_NEW_CONSOLE or DETACHED_PROCESS). CTRL+C and CTRL+BREAK events are sent to all processes which share that console, so all processes in the console process group will receive the event/signal.

For situations requiring shared I/O with a "parent", such as a shim, I'll just use null handlers for signals in the parent while waiting for the "child" process to finish.

ref: MS ~ Creation of a Console @@ https://archive.is/yFRT5
ref: MS ~ CTRL+C and CTRL+BREAK Signals @@ https://archive.is/6T140

let handle = unsafe { OpenProcess(PROCESS_TERMINATE, FALSE, pid as DWORD) };
if pid <= 0 {
return Err(type_error(
"Process id (pid) cannot be negative or zero on Windows.",
Copy link
Member

Choose a reason for hiding this comment

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

Wrt CTRL_C_EVENT and CTRL_BREAK_EVENT: Windows supports sending them to pid 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL :) made some changes

match self {
WindowsSignal::Sigint(ctrl_c) => ctrl_c.recv().await,
WindowsSignal::Sigbreak(ctrl_break) => ctrl_break.recv().await,
}
Copy link
Member

Choose a reason for hiding this comment

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

We could also listen to CTRL_CLOSE_EVENT and map it to SIGHUP. Node does this too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There doesn't seem to be a type for ctrl_close in tokio::signal::windows though

@bartlomieju bartlomieju added this to the 1.23 milestone Jun 1, 2022
Copy link
Member

@piscisaureus piscisaureus left a comment

Choose a reason for hiding this comment

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

LGTM, thank you @GJZwiers!

@rivy
Copy link
Contributor

rivy commented Jun 12, 2022

@GJZwiers , thanks for this work!

Closes #9995 and #10236.

This only partially fixes #9995 (which is requesting broad signal handler parity for WinOS). It definitely goes a long way toward the goal by implementing the most commonly needed signals ('SIGBREAK' and 'SIGINT'). But, I wouldn't close #9995 based on the partial implementation.

@GJZwiers
Copy link
Contributor Author

@GJZwiers , thanks for this work!

Closes #9995 and #10236.

This only partially fixes #9995 (which is requesting broad signal handler parity for WinOS). It definitely goes a long way toward the goal by implementing the most commonly needed signals ('SIGBREAK' and 'SIGINT'). But, I wouldn't close #9995 based on the partial implementation.

Ah my bad, I'll update the description

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

LGTM, that's a great improvement @GJZwiers!

Note to self: remember to credit https://github.com/juzi5201314 when landing

@bartlomieju bartlomieju merged commit 24571a3 into denoland:main Jun 13, 2022
@GJZwiers GJZwiers deleted the sigint_sigbreak_windows branch June 14, 2022 20:12
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.

Support for windows ctrl-c signal
5 participants