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
next problem.
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
have...).
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
the handler.
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.
--
Mike Hull
Coversant, Inc.
http://www.coversant.net
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list