-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Don't close pipes used for signal handlers in MT #8465
Don't close pipes used for signal handlers in MT #8465
Conversation
Whatever that fork is disabled in MT: we still fork/exec to run executables, and we must reset signals to SIG_DFL and close the IO pipe in the forked process before calling exec. |
@ysbaddaden you mean to extract these lines e5b401f#diff-d7e78211632011c14cdae00909be40ddR239-R241 without the pipe close, right? It would be good to have at least a manual spec to ensure the behavior of signals is not broken. Otherwise it is doing changes in the dark. Do you have some use case/example to stress that signals are handled as expected? |
Actually, not closing the reader part of the pipe fixes #8375 for me. I don't know why, but it's okayish: even if the child process receives a signal it won't write it to the pipe (the writer part is closed) and the reader file descriptor will be closed by diff --git a/src/signal.cr b/src/signal.cr
index f4c094f25..1737b85a0 100644
--- a/src/signal.cr
+++ b/src/signal.cr
@@ -242,7 +242,7 @@ module Crystal::Signal
LibC.signal(signal, LibC::SIG_DFL) if signal.set?
end
ensure
- @@pipe.each(&.close)
+ writer.close
end
private def self.reader NOTE: we disable signals for the current thread (sigmask) for reasons explained in comments and in d195adf, 979a528 and e5b401f. We must reenable signals prior to exec (otherwise the exec'd process would have disabled signals by default, which is unexpected) and should reset signal handlers before that, so we don't handle signals in the forked process (until exec). |
@ysbaddaden The signals are still being reset and the pipes have |
Correction... @ysbaddaden you're right, we need to reenable the signals. I'll move the fix into the |
This was actually a leftover in this commit: crystal-lang@f544b22
de22eb7
to
f55e681
Compare
Yes. The sigset is updated before changing the signal handler so I think we don't even need to ever close the pipe (even without MT). LLVM could reorder instructions and cause the signal handler to be set before the sigset, but the likelihood for a thread to fork while another adds a signal handler and the forked child to receive a signal (sending it to the parent) before exec is very very tiny —and impossible with a single thread anyway. |
This should fix #8375
In MT mode,
fork
is disabled and the event loop is not reinitialized. In other words,fork
only works to run a process (i.e: do anexec
) right away, without any context switch or IO operations in between.