-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Fix possible deadlocks on PosixSignalRegistration disposal on Windows #124893
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
base: main
Are you sure you want to change the base?
Changes from all commits
8d4df78
346a77b
0bcf834
adfcccb
d9ab110
1a9751f
7f9a9de
e2184ec
44e6763
d27d330
b369a3c
6ed26b2
c4250f3
43b751f
481abee
a7ed82c
5af264a
5e59198
41eb483
2082289
781813f
54be37c
23a28b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -161,6 +161,98 @@ public void TestCreateNewProcessGroup_HandlerReceivesExpectedSignal(PosixSignal | |||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] | ||||||||
| [MemberData(nameof(SignalTestData))] | ||||||||
| public void SignalHandler_CanDisposeInHandler(PosixSignal signal) | ||||||||
| { | ||||||||
| const string PosixSignalRegistrationCreatedMessage = "PosixSignalRegistration created..."; | ||||||||
| const string PosixSignalHandlerStartedMessage = "PosixSignalHandlerStartedMessage created..."; | ||||||||
| const string PosixSignalHandlerDisposedMessage = "PosixSignalHandlerDisposedMessage created..."; | ||||||||
|
Comment on lines
+164
to
+170
mrek-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
|
||||||||
| var remoteInvokeOptions = new RemoteInvokeOptions { CheckExitCode = false }; | ||||||||
| remoteInvokeOptions.StartInfo.RedirectStandardOutput = true; | ||||||||
| if (OperatingSystem.IsWindows()) | ||||||||
| { | ||||||||
| remoteInvokeOptions.StartInfo.CreateNewProcessGroup = true; | ||||||||
| } | ||||||||
|
|
||||||||
| using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke( | ||||||||
| (signalStr) => | ||||||||
| { | ||||||||
| PosixSignal expectedSignal = Enum.Parse<PosixSignal>(signalStr); | ||||||||
| using ManualResetEvent receivedSignalEvent = new ManualResetEvent(false); | ||||||||
| ReEnableCtrlCHandlerIfNeeded(expectedSignal); | ||||||||
|
|
||||||||
| PosixSignalRegistration? p = null; | ||||||||
| p = PosixSignalRegistration.Create(expectedSignal, (ctx) => | ||||||||
| { | ||||||||
| Console.WriteLine(PosixSignalHandlerStartedMessage); | ||||||||
| Assert.Equal(expectedSignal, ctx.Signal); | ||||||||
|
|
||||||||
| Assert.NotNull(p); | ||||||||
| p?.Dispose(); | ||||||||
|
|
||||||||
| // Used for checking that Dispose returned and did not get stuck | ||||||||
| Console.WriteLine(PosixSignalHandlerDisposedMessage); | ||||||||
|
|
||||||||
| receivedSignalEvent.Set(); | ||||||||
| ctx.Cancel = true; | ||||||||
| }); | ||||||||
|
|
||||||||
| Console.WriteLine(PosixSignalRegistrationCreatedMessage); | ||||||||
|
|
||||||||
| // Wait for signal which unregisters itself | ||||||||
| Assert.True(receivedSignalEvent.WaitOne(WaitInMS)); | ||||||||
|
|
||||||||
| // Wait for second signal which should terminate process by default system handler | ||||||||
mrek-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| Thread.Sleep(1000); | ||||||||
|
|
||||||||
| // If we did not terminated yet, return failure exit code | ||||||||
| return -1; | ||||||||
| }, | ||||||||
| arg: $"{signal}", | ||||||||
| remoteInvokeOptions); | ||||||||
|
|
||||||||
| while (!remoteHandle.Process.StandardOutput.ReadLine().EndsWith(PosixSignalRegistrationCreatedMessage)) | ||||||||
| { | ||||||||
| Thread.Sleep(20); | ||||||||
| } | ||||||||
|
|
||||||||
| try | ||||||||
| { | ||||||||
| SendSignal(signal, remoteHandle.Process.Id); | ||||||||
|
|
||||||||
| while (!remoteHandle.Process.StandardOutput.ReadLine().EndsWith(PosixSignalHandlerStartedMessage)) | ||||||||
| { | ||||||||
| Thread.Sleep(20); | ||||||||
| } | ||||||||
|
Comment on lines
+225
to
+228
|
||||||||
|
|
||||||||
| while (!remoteHandle.Process.StandardOutput.ReadLine().EndsWith(PosixSignalHandlerDisposedMessage)) | ||||||||
| { | ||||||||
| Thread.Sleep(20); | ||||||||
| } | ||||||||
|
Comment on lines
+216
to
+233
|
||||||||
|
|
||||||||
|
Comment on lines
+216
to
+234
|
||||||||
| SendSignal(signal, remoteHandle.Process.Id); | ||||||||
|
|
||||||||
| Assert.True(remoteHandle.Process.WaitForExit(WaitInMS)); | ||||||||
| Assert.True(remoteHandle.Process.StandardOutput.EndOfStream); | ||||||||
| if (OperatingSystem.IsWindows()) | ||||||||
| { | ||||||||
| Assert.Equal(unchecked((int)0xC000013A), remoteHandle.Process.ExitCode); // STATUS_CONTROL_C_EXIT | ||||||||
| } | ||||||||
| else | ||||||||
| { | ||||||||
| Assert.Equal(0, remoteHandle.Process.ExitCode); | ||||||||
|
||||||||
| Assert.Equal(0, remoteHandle.Process.ExitCode); | |
| int expectedExitCode = 128 + (int)signal; | |
| Assert.Equal(expectedExitCode, remoteHandle.Process.ExitCode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test uses
SignalTestData, which on Unix includes signals likeSIGCHLD/SIGWINCH(default: ignored) andSIGTSTP/SIGTTIN/SIGTTOU(default: stop, not terminate). The test expects the second signal to terminate the process, so it will fail or hang/return -1 for those signals. Limit this test’s data to signals whose default action is process termination (e.g., SIGINT/SIGQUIT/SIGTERM), or make the expected outcome conditional per-signal.