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

Implement PosixSignal API #54136

Merged
merged 65 commits into from
Jul 8, 2021
Merged

Implement PosixSignal API #54136

merged 65 commits into from
Jul 8, 2021

Conversation

tmds
Copy link
Member

@tmds tmds commented Jun 14, 2021

Implements #50527.

I still need to add tests.

Can you do a first review of the implementation?

cc @janvorli @jkotas @stephentoub @davidfowl @bartonjs

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@@ -775,6 +775,26 @@ public sealed partial class OptionalAttribute : System.Attribute
{
public OptionalAttribute() { }
}
public enum PosixSignal
Copy link
Member Author

Choose a reason for hiding this comment

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

I've manually added these to the ref file, I don't know if there is an automated way.

Copy link
Member

Choose a reason for hiding this comment

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

The automated way is documented in https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/updating-ref-source.md . It would be a good idea to rerun the automated process to make sure that the formatting is right.

Copy link
Member

Choose a reason for hiding this comment

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

But beware, it currently removes attributes...

Copy link
Member Author

Choose a reason for hiding this comment

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

I ran it and copied in the PosixSignal bits.
I'm surprised to see internal instead of private on the PosixSignalRegistration constructor.

@andyleejordan
Copy link
Member

Hey, I just wanted to drop by and say it's really exciting to see this work! 🥳

@tmds
Copy link
Member Author

tmds commented Jun 18, 2021

The implementation has changed a bit since the initial PR.

  • Positive PosixSignal values can now be used as raw signal numbers.
  • Terminal configuration on SIGCONT/SIGCHLD can be canceled, as requested by @alexrp.

The implementation will call the original sa_handler/sa_sigaction if one was set.

It handles specifically what is cancelable by the runtime using PosixSignal API:

  • Not terminating for SIGTERM/SIGINT/SIGQUIT
  • Skipping terminal configuration for SIGCHLD/SIGCONT.

I'll look at writing some tests next week.

@alexrp
Copy link
Contributor

alexrp commented Jun 18, 2021

Just posting here as well so it doesn't get missed: I think it's worth considering a rename to UnixSignal for consistency reasons; see this comment.

@lambdageek
Copy link
Member

@tmds what's the expected behavior if users set up a handler for a signal that the runtime uses internally.

For example, the mono GC uses signals on non-Apple Unixes to suspend threads that are in preemptive mode - we pick the signal dynamically and use pthread_kill for signalling.

static int suspend_signal_num = -1;
static int restart_signal_num = -1;
static int abort_signal_num = -1;
static sigset_t suspend_signal_mask;
static sigset_t suspend_ack_signal_mask;
static void
signal_add_handler (int signo, void (*handler)(int, siginfo_t *, void *), int flags)
{
struct sigaction sa;
int ret;
sa.sa_sigaction = handler;
sigfillset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO | flags;
ret = sigaction (signo, &sa, NULL);
g_assert (ret != -1);
}
static int
abort_signal_get (void)
{
#if defined(HOST_ANDROID)
return SIGTTIN;
#elif defined (__OpenBSD__)
return SIGUSR1;
#elif defined (SIGRTMIN)
static int abort_signum = -1;
if (abort_signum == -1)
abort_signum = mono_threads_suspend_search_alternative_signal ();
return abort_signum;
#elif defined (SIGTTIN)
return SIGTTIN;
#else
g_error ("unable to get abort signal");
#endif
}
static int
suspend_signal_get (void)
{
#if defined(HOST_ANDROID)
return SIGPWR;
#elif defined (SIGRTMIN)
static int suspend_signum = -1;
if (suspend_signum == -1)
suspend_signum = mono_threads_suspend_search_alternative_signal ();
return suspend_signum;
#else
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
return SIGXFSZ;
#else
return SIGPWR;
#endif
#endif
}
static int
restart_signal_get (void)
{
#if defined(HOST_ANDROID)
return SIGXCPU;
#elif defined (SIGRTMIN)
static int restart_signum = -1;
if (restart_signum == -1)
restart_signum = mono_threads_suspend_search_alternative_signal ();
return restart_signum;
#else
return SIGXCPU;
#endif
}

Should we have some mechanism that the runtime could use to prevent users from installing handlers for these signals?

@tmds
Copy link
Member Author

tmds commented Jul 5, 2021

CI fail is unrelated.

@stephentoub stephentoub merged commit a25bece into dotnet:main Jul 8, 2021
@stephentoub
Copy link
Member

Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.