Signals on Windows

While looking at signal support in IronRuby, I played with the signal and raise functions that are available in the C runtime. It turns out that these functions are much more limited than their Unix counterparts. On Unix, kill can be used to send a signal to another process, enabling cross-process communication.

However, the CRT raise function does not take a process id. It can only send a synchronous signal on the same thread to the process it is being called from. This does not seem to be of much use. SIGINT (Ctrl-C) can also be dealt with using SetConsoleCtrlHandler in unmanaged code, or Console.CancelKeyPress in managed code, and the Windows runs the handler on a separate thread. SIGILL, SIGSEGV, and SIGTERM are not generated on Windows NT. So that only leaves SIGABRT and SIGFPE. Not sure how important these are.

If asynchronous signals were truly supported on existing threads, this would present challenges to using managed code to handle the signals. The thread may not be in an interruptible state when the handler is run. If the handler triggers a GC or stack-walk, that would cause trouble. Also, running managed code can allocate memory since the code may not have been JITed. Doing such heavy-weight operations in the handler would also lead to trouble. Python ("they can only occur between the ``atomic'' instructions of the Python interpreter") and Perl ("to avoid these problems signals are deferred") seem to defer running of the signal handler from a safe point, or run it on a new thread like SIGINT on Windows.

I am attaching a test case to use signals from managed code if anyone wants to play with it. All handlers are run synchronously. Ctrl-C is run asynchronously but on a new thread.

signal.cs