//
using NUnit.Framework;
+using NUnit.Framework.SyntaxHelpers;
using System;
using System.Text;
using System.Threading;
using Mono.Unix;
using Mono.Unix.Native;
+namespace NUnit.Framework.SyntaxHelpers { class Dummy {} }
+
namespace MonoTests.Mono.Unix {
[TestFixture]
public class UnixSignalTest {
+
+ // helper method to create a thread waiting on a UnixSignal
+ static Thread CreateWaitSignalThread (UnixSignal signal, int timeout)
+ {
+ Thread t1 = new Thread(delegate() {
+ DateTime start = DateTime.Now;
+ bool r = signal.WaitOne (timeout, false);
+ DateTime end = DateTime.Now;
+ Assert.AreEqual (signal.Count, 1);
+ Assert.AreEqual (r, true);
+ if ((end - start) > new TimeSpan (0, 0, timeout/1000))
+ throw new InvalidOperationException ("Signal slept too long");
+ });
+ return t1;
+ }
+
+ // helper method to create a two-thread test
+ static void MultiThreadTest (UnixSignal signal, int timeout, ThreadStart tstart)
+ {
+ Thread t1 = CreateWaitSignalThread (signal, timeout);
+ Thread t2 = new Thread (tstart);
+ t1.Start ();
+ t2.Start ();
+ t1.Join ();
+ t2.Join ();
+ }
+
+ [Test]
+ public void TestNestedInvocation()
+ {
+ UnixSignal s = new UnixSignal(Signum.SIGINT);
+ Thread a = new Thread(delegate() {
+ bool r = s.WaitOne (1000, false);
+ });
+ Thread b = new Thread(delegate() {
+ bool r = s.WaitOne (500, false);
+ });
+ a.Start();
+ b.Start();
+ a.Join();
+ b.Join();
+ }
+
+ [Test]
+ public void TestWaitAnyFailsWithMore64Signals()
+ {
+ UnixSignal s1 = new UnixSignal(Signum.SIGINT);
+ UnixSignal[] signals = new UnixSignal[65];
+ for (int i=0; i<65; ++i)
+ signals[i] = s1;
+
+ Assert.That(UnixSignal.WaitAny(signals, new TimeSpan(0,0,1)), Is.EqualTo(-1));
+ }
+
+ [Test]
+ public void TestConcurrentWaitOne()
+ {
+ UnixSignal s1 = new UnixSignal(Signum.SIGINT);
+ UnixSignal s2 = new UnixSignal(Signum.SIGINT);
+ Thread a = CreateWaitSignalThread(s1, 10000);
+ Thread b = CreateWaitSignalThread(s2, 5000);
+ Thread c = new Thread (delegate () {
+ Thread.Sleep (1000);
+ Stdlib.raise (Signum.SIGINT);
+ });
+ a.Start();
+ b.Start();
+ c.Start();
+ a.Join();
+ b.Join();
+ c.Join();
+ Assert.That(s1.Count, Is.EqualTo(1), "Expected 1 signal raised");
+ Assert.That(s2.Count, Is.EqualTo(1), "Expected 1 signal raised");
+ }
+
+ [Test]
+ public void TestConcurrentWaitOneSameInstance()
+ {
+ UnixSignal s1 = new UnixSignal(Signum.SIGINT);
+ Thread a = CreateWaitSignalThread(s1, 10000);
+ Thread b = CreateWaitSignalThread(s1, 10000);
+ Thread c = new Thread (delegate () {
+ Thread.Sleep (500);
+ Stdlib.raise (Signum.SIGINT);
+ });
+ a.Start();
+ b.Start();
+ c.Start();
+ a.Join();
+ b.Join();
+ c.Join();
+ }
+
+ [Test]
+ public void TestSignumProperty ()
+ {
+ UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
+ Assert.That (signal1.Signum, Is.EqualTo (Signum.SIGSEGV));
+ }
+
+ [Test]
+ [Category ("NotOnMac")]
+ public void TestRealTimeCstor ()
+ {
+ RealTimeSignum rts = new RealTimeSignum (0);
+ using (UnixSignal s = new UnixSignal (rts))
+ {
+ Assert.That(s.IsRealTimeSignal);
+ Assert.That(s.RealTimeSignum, Is.EqualTo (rts));
+ }
+ }
+
+ [Test]
+ [ExpectedException]
+ [Category ("NotOnMac")]
+ public void TestSignumPropertyThrows ()
+ {
+ UnixSignal signal1 = new UnixSignal (new RealTimeSignum (0));
+ Signum s = signal1.Signum;
+ }
+
+ [Test]
+ [Category ("NotOnMac")]
+ public void TestRealTimeSignumProperty ()
+ {
+ RealTimeSignum rts = new RealTimeSignum (0);
+ UnixSignal signal1 = new UnixSignal (rts);
+ Assert.That (signal1.RealTimeSignum, Is.EqualTo (rts));
+ }
+
+ [Test]
+ [ExpectedException]
+ [Category ("NotOnMac")]
+ public void TestRealTimePropertyThrows ()
+ {
+ UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
+ RealTimeSignum s = signal1.RealTimeSignum;
+ }
+
+ [Test]
+ [Category ("NotOnMac")]
+ public void TestRaiseRTMINSignal ()
+ {
+ RealTimeSignum rts = new RealTimeSignum (0);
+ using (UnixSignal signal = new UnixSignal (rts))
+ {
+ MultiThreadTest (signal, 5000, delegate() {
+ Thread.Sleep (1000);
+ Stdlib.raise (rts);
+ });
+ }
+ }
+
+ [Test]
+ [Category ("NotOnMac")]
+ public void TestRaiseRTMINPlusOneSignal ()
+ {
+ /*this number is a guestimate, but it's ok*/
+ for (int i = 1; i < 10; ++i) {
+ RealTimeSignum rts = new RealTimeSignum (i);
+ UnixSignal signal;
+ try {
+ signal = new UnixSignal (rts);
+ } catch (ArgumentException) { /*skip the ones that are unavailable*/
+ continue;
+ }
+ using (signal)
+ {
+ MultiThreadTest (signal, 5000, delegate() {
+ Thread.Sleep(1000);
+ Stdlib.raise(rts);
+ });
+ }
+ return;
+ }
+ Assert.IsTrue (false, "#1 No available RT signal");
+ }
+
+ [Test]
+ [Category ("NotOnMac")]
+ public void TestCanRegisterRTSignalMultipleTimes ()
+ {
+ /*this number is a guestimate, but it's ok*/
+ for (int i = 1; i < 10; ++i) {
+ RealTimeSignum rts = new RealTimeSignum (i);
+ UnixSignal signal;
+ try {
+ signal = new UnixSignal (rts);
+ } catch (ArgumentException) { /*skip the ones that are unavailable*/
+ continue;
+ }
+ try {
+ using (UnixSignal signal2 = new UnixSignal (rts))
+ {
+ //ok
+ return;
+ }
+ } catch (ArgumentException) { /*skip the ones that are unavailable*/
+ Assert.IsTrue (false, "#1 Could not register second signal handler");
+ }
+ }
+ Assert.IsTrue (false, "#2 No available RT signal");
+ }
+
[Test]
public void TestRaise ()
{
UnixSignal b = new UnixSignal (Signum.SIGINT);
Stdlib.raise (Signum.SIGINT);
+ SleepUntilSignaled (a);
Assert.AreEqual (a.Count, 1);
Assert.AreEqual (b.Count, 1);
b.Reset ();
Stdlib.raise (Signum.SIGINT);
+ SleepUntilSignaled (b);
Assert.AreEqual (b.Count, 1);
b.Close ();
}
+ static void SleepUntilSignaled (UnixSignal s)
+ {
+ for (int i = 0; i < 10; ++i) {
+ if (s.Count > 0)
+ break;
+ Thread.Sleep (100);
+ }
+ }
+
[Test]
public void TestDispose2 ()
{
UnixSignal b = new UnixSignal (Signum.SIGINT);
Stdlib.raise (Signum.SIGINT);
+ SleepUntilSignaled (a);
Assert.AreEqual (a.Count, 1);
Assert.AreEqual (b.Count, 1);
a.Reset ();
Stdlib.raise (Signum.SIGINT);
+ SleepUntilSignaled (a);
Assert.AreEqual (a.Count, 1);
a.Close ();
const int StormCount = 100000;
[Test]
+ [Category("NotOnMac")] // OSX signal storming will not deliver every one
public void TestRaiseStorm ()
{
UnixSignal[] usignals = CreateSignals (signals);
}
[Test]
+ [Category("NotOnMac")] // OSX signal storming will not deliver every one
public void TestAddRemove ()
{
UnixSignal[] usignals = CreateSignals (signals);
}
[Test]
+ [Category("NotOnMac")] // OSX signal storming will not deliver every one
public void TestWaitAny ()
{
UnixSignal[] usignals = CreateSignals (signals);