[Mono-dev] Need help with signal handlers.
mike.hull at coversant.net
Sat Aug 20 12:13:02 EDT 2005
Jonathan Pryor wrote:
>On Fri, 2005-08-19 at 15:43 -0700, Mike Hull wrote:
>>I'm trying to pass signals received with signal.h into managed code.
>>After I mono_runtime_exec_managed_code I can not receive signals using
>>signal(sig,signal_handler). If I don't mono_runtime_exec_managed_code I
>>receive the signals just fine.
>You're in a world of hurt. :-)
>Mono.Posix.Syscall.signal() is horribly, horribly broken. How broken?
>It takes a raw `int' as the signal number to catch. You *cannot* use
>Mono.Posix.Signals because those don't match *ANY* operating system's
>values. Consequently, it's inherently non-portable.
>Mono.Unix.Stdlib.signal() is the replacement, but it isn't without the
>The larger problem is one of reentrancy: Mono is not reentrant, and
>neither is the P/Invoke layer.
>Reentrancy is similar to thread safety, but different: when a signal
>occurs, a (potentially random) process thread is "hijacked", a new stack
>frame is added (or worse, the current stack frame is re-used), and the
>signal handler is executed. (Since an existing thread is re-used, and
>probably the most recently executing thread, normal thread-safety tricks
>such as mutexes won't work -- you have to protect against the *same*
>thread re-entering the currently executing function. Fun.)
>The only safe thing you can do is call other reentrant functions, and
>*most* functions are NOT reentrant (malloc(3) isn't, neither is free(2),
>function calls are "iffy" depending on how much stack space you
>In short, signal handlers are a whole new world of pain. Managed code
>only makes things worse, since the entire P/Invoke layer isn't
>reentrant, so you risk many unknowns just trying to use a managed
>delegate as a signal handler, never mind doing anything complicated from
>Thus, the advice: assuming you risk using a signal handler in managed
>code, all you can do from managed code is modify a variable. That's it.
>Anything else, *especially* a P/Invoke call, is suspect.
>Alternatively, all your signal handlers should be implemented in C. You
>could hook them up from C#. If you do this, take care that your handler
>only calls reentrant functions.
> - Jon
So what if I passed the C program that the C# application is embedded in
a ManualResetEvent when I want it to initialize the signal handlers?
Instead of calling a method on the managed object. Then the thread that
is waiting on that ManualResetEvent queires a "GetSiganl" InternalCall
that returns the signal.
More information about the Mono-devel-list