[Mono-dev] Control-C handler

Jonathan Pryor jonpryor at vt.edu
Wed Feb 6 12:33:06 EST 2008

On Mon, 2008-02-04 at 16:27 -0500, Jonathan Pryor wrote:
> On Mon, 2008-02-04 at 12:38 +0100, Paolo Molaro wrote:
> > On 01/28/08 Jonathan Pryor wrote:
> > You should write a test case to stress-test this code and see if it
> > behaves correctly under a storm of signals, say at least 100k signals.
> > You should check that no signal was lost. Repeat the same while one
> > thread adds/removes handlers. Repeat with two threads doing a WaitAny()
> > and using more than one signal.
> See attached test program.  It works if all Stdlib.raise() calls are
> from the same thread.

The failure seen when using Stdlib.raise() from multiple threads has
been fixed; see the attached patch to signal.c (which is a diff against
the previous version of the patch, not a complete re-send of
UnixSignal-related changes).

In short, using g_atomic_int_inc() is the solution.

> >  Repeat with two threads calling kill()
> > to send the signal. Do all of this on a SMP box.
> ...and it fails if I use Syscall.kill() to send the signal, or I use
> multiple threads to call Stdlib.raise().  (Stdlib.raise() invocation is
> synchronous, hence it works if only one thread calls it.)

kill(2), however, is giving me fits.  It seems that the signal handler
is not invoked as many times as kill(2) is used.  See the attached
`ms.c' program, which is a purely pthreads-based sample program that
tries to mimic what signal.c is doing.

Compile normally, and things work properly:

        $ gcc -g -Wall `pkg-config --cflags --libs glib-2.0` ms.c -o ms -lpthread
        $ ./ms
        1500000 == 1500000? 1
         kill count=100000
        total count=100000

(Output will vary, as some things are random.  What's important is that
the numbers match on the first line of output.)

Tell it to use kill(2), and things go south:

        $ gcc -g -Wall -DKILL `pkg-config --cflags --libs glib-2.0` ms.c -o ms -lpthread
        $ ./ms
        1382858 == 1900000? 0
         kill count=100000
        total count=72782

Notice that the numbers don't match.  I've tried `strace -f'ing it, and
strace shows that there are more kill(2) calls than there are signal
handler invocations.

As far as I can tell, the counts are off with kill(2) because the kernel
"loses" some of the signals.  I've messed around with using
sigaction(2), in particular setting sa_flags to SA_NODEFER and other
values, and they have no visible effect on the program's behavior.

So given that I seem to be hitting a fundamental limitation of kill(2),
is UnixSignal plus the attached signal.c patch sufficient for 1.9?

 - Jon

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signal.diff
Type: text/x-patch
Size: 911 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080206/8eefc55c/attachment.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ms.c
Type: text/x-csrc
Size: 2113 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080206/8eefc55c/attachment-0001.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: us-test-lupus.cs
Type: text/x-csharp
Size: 3197 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080206/8eefc55c/attachment-0002.bin 

More information about the Mono-devel-list mailing list