2014-08-13 10:39:27 +01:00
|
|
|
//
|
|
|
|
// UnixSignalTest.cs - NUnit Test Cases for Mono.Unix.UnixSignal
|
|
|
|
//
|
|
|
|
// Authors:
|
|
|
|
// Jonathan Pryor <jonpryor@vt.edu>
|
|
|
|
//
|
|
|
|
// (C) 2008 Jonathan Pryor
|
|
|
|
//
|
|
|
|
|
|
|
|
using NUnit.Framework;
|
2017-04-10 11:41:01 +00:00
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
using System;
|
2017-10-19 20:04:20 +00:00
|
|
|
using System.Diagnostics;
|
2014-08-13 10:39:27 +01:00
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using Mono.Unix;
|
2015-08-26 07:17:56 -04:00
|
|
|
using Mono.Unix.Android;
|
2014-08-13 10:39:27 +01:00
|
|
|
using Mono.Unix.Native;
|
2017-04-10 11:41:01 +00:00
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
namespace MonoTests.Mono.Unix {
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
[TestFixture, Category ("NotOnWindows")]
|
2014-08-13 10:39:27 +01:00
|
|
|
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() {
|
2017-10-19 20:04:20 +00:00
|
|
|
var sw = Stopwatch.StartNew ();
|
2014-08-13 10:39:27 +01:00
|
|
|
bool r = signal.WaitOne (timeout, false);
|
2017-10-19 20:04:20 +00:00
|
|
|
sw.Stop ();
|
2014-08-13 10:39:27 +01:00
|
|
|
Assert.AreEqual (signal.Count, 1);
|
|
|
|
Assert.AreEqual (r, true);
|
2017-10-19 20:04:20 +00:00
|
|
|
if (sw.Elapsed > new TimeSpan (0, 0, timeout/1000))
|
2014-08-13 10:39:27 +01:00
|
|
|
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]
|
2015-09-02 12:36:57 -04:00
|
|
|
[Category ("AndroidNotWorking")] // Crashes (silently) the runtime in similar fashion to real-time signals
|
2014-08-13 10:39:27 +01:00
|
|
|
public void TestSignumProperty ()
|
|
|
|
{
|
|
|
|
UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
|
|
|
|
Assert.That (signal1.Signum, Is.EqualTo (Signum.SIGSEGV));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
[Category ("NotOnMac")]
|
|
|
|
public void TestRealTimeCstor ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2014-08-13 10:39:27 +01:00
|
|
|
RealTimeSignum rts = new RealTimeSignum (0);
|
|
|
|
using (UnixSignal s = new UnixSignal (rts))
|
|
|
|
{
|
|
|
|
Assert.That(s.IsRealTimeSignal);
|
|
|
|
Assert.That(s.RealTimeSignum, Is.EqualTo (rts));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
[Category ("NotOnMac")]
|
|
|
|
public void TestSignumPropertyThrows ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2017-08-21 15:34:15 +00:00
|
|
|
|
|
|
|
Assert.Throws<InvalidOperationException> (() => {
|
|
|
|
UnixSignal signal1 = new UnixSignal (new RealTimeSignum (0));
|
|
|
|
Signum s = signal1.Signum;
|
|
|
|
});
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
[Category ("NotOnMac")]
|
|
|
|
public void TestRealTimeSignumProperty ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2014-08-13 10:39:27 +01:00
|
|
|
RealTimeSignum rts = new RealTimeSignum (0);
|
|
|
|
UnixSignal signal1 = new UnixSignal (rts);
|
|
|
|
Assert.That (signal1.RealTimeSignum, Is.EqualTo (rts));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
[Category ("NotOnMac")]
|
|
|
|
public void TestRealTimePropertyThrows ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
2017-08-21 15:34:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
Assert.Throws<InvalidOperationException> (() => {
|
|
|
|
UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
|
|
|
|
RealTimeSignum s = signal1.RealTimeSignum;
|
|
|
|
});
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
[Category ("NotOnMac")]
|
|
|
|
public void TestRaiseRTMINSignal ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2014-08-13 10:39:27 +01:00
|
|
|
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 ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2014-08-13 10:39:27 +01:00
|
|
|
/*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 ()
|
|
|
|
{
|
2015-08-26 07:17:56 -04:00
|
|
|
if (!TestHelper.CanUseRealTimeSignals ())
|
|
|
|
return;
|
2014-08-13 10:39:27 +01:00
|
|
|
/*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 ()
|
|
|
|
{
|
|
|
|
Thread t1 = new Thread (delegate () {
|
|
|
|
using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
|
2017-10-19 20:04:20 +00:00
|
|
|
var sw = Stopwatch.StartNew ();
|
2014-08-13 10:39:27 +01:00
|
|
|
bool r = a.WaitOne (5000, false);
|
2017-10-19 20:04:20 +00:00
|
|
|
sw.Stop ();
|
2014-08-13 10:39:27 +01:00
|
|
|
Assert.AreEqual (a.Count, 1);
|
|
|
|
Assert.AreEqual (r, true);
|
2017-10-19 20:04:20 +00:00
|
|
|
if (sw.Elapsed > new TimeSpan (0, 0, 5))
|
2014-08-13 10:39:27 +01:00
|
|
|
throw new InvalidOperationException ("Signal slept too long");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Thread t2 = new Thread (delegate () {
|
|
|
|
Thread.Sleep (1000);
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
});
|
|
|
|
t1.Start ();
|
|
|
|
t2.Start ();
|
|
|
|
t1.Join ();
|
|
|
|
t2.Join ();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestRaiseAny ()
|
|
|
|
{
|
|
|
|
Thread t1 = new Thread (delegate () {
|
|
|
|
using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
|
2017-10-19 20:04:20 +00:00
|
|
|
var sw = Stopwatch.StartNew ();
|
2014-08-13 10:39:27 +01:00
|
|
|
int idx = UnixSignal.WaitAny (new UnixSignal[]{a}, 5000);
|
2017-10-19 20:04:20 +00:00
|
|
|
sw.Stop ();
|
2014-08-13 10:39:27 +01:00
|
|
|
Assert.AreEqual (idx, 0);
|
|
|
|
Assert.AreEqual (a.Count, 1);
|
2017-10-19 20:04:20 +00:00
|
|
|
if (sw.Elapsed > new TimeSpan (0, 0, 5))
|
2014-08-13 10:39:27 +01:00
|
|
|
throw new InvalidOperationException ("Signal slept too long");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Thread t2 = new Thread (delegate () {
|
|
|
|
Thread.Sleep (1000);
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
});
|
|
|
|
t1.Start ();
|
|
|
|
t2.Start ();
|
|
|
|
t1.Join ();
|
|
|
|
t2.Join ();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestSeparation ()
|
|
|
|
{
|
|
|
|
Thread t1 = new Thread (delegate () {
|
|
|
|
using (UnixSignal a = new UnixSignal (Signum.SIGINT))
|
|
|
|
using (UnixSignal b = new UnixSignal (Signum.SIGTERM)) {
|
2017-10-19 20:04:20 +00:00
|
|
|
var sw = Stopwatch.StartNew ();
|
2014-08-13 10:39:27 +01:00
|
|
|
int idx = UnixSignal.WaitAny (new UnixSignal[]{a, b}, 5000);
|
2017-10-19 20:04:20 +00:00
|
|
|
sw.Stop ();
|
2014-08-13 10:39:27 +01:00
|
|
|
Assert.AreEqual (idx, 1);
|
|
|
|
Assert.AreEqual (a.Count, 0);
|
|
|
|
Assert.AreEqual (b.Count, 1);
|
2017-10-19 20:04:20 +00:00
|
|
|
if (sw.Elapsed > new TimeSpan (0, 0, 5))
|
2014-08-13 10:39:27 +01:00
|
|
|
throw new InvalidOperationException ("Signal slept too long");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Thread t2 = new Thread (delegate () {
|
|
|
|
Thread.Sleep (1000);
|
|
|
|
Stdlib.raise (Signum.SIGTERM);
|
|
|
|
});
|
|
|
|
t1.Start ();
|
|
|
|
t2.Start ();
|
|
|
|
t1.Join ();
|
|
|
|
t2.Join ();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestNoEmit ()
|
|
|
|
{
|
|
|
|
using (UnixSignal u = new UnixSignal (Signum.SIGINT)) {
|
2017-10-19 20:04:20 +00:00
|
|
|
var sw = Stopwatch.StartNew ();
|
2014-08-13 10:39:27 +01:00
|
|
|
bool r = u.WaitOne (5100, false);
|
|
|
|
Assert.AreEqual (r, false);
|
2017-10-19 20:04:20 +00:00
|
|
|
sw.Stop ();
|
|
|
|
if (sw.Elapsed < new TimeSpan (0, 0, 5))
|
|
|
|
throw new InvalidOperationException ("Signal didn't block for 5s; blocked for " + sw.Elapsed.TotalSeconds.ToString());
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestNoEmitAny ()
|
|
|
|
{
|
|
|
|
using (UnixSignal u = new UnixSignal (Signum.SIGINT)) {
|
|
|
|
int idx = UnixSignal.WaitAny (new UnixSignal[]{u}, 5100);
|
|
|
|
Assert.AreEqual (idx, 5100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestDispose1 ()
|
|
|
|
{
|
|
|
|
UnixSignal a = new UnixSignal (Signum.SIGINT);
|
|
|
|
UnixSignal b = new UnixSignal (Signum.SIGINT);
|
|
|
|
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
SleepUntilSignaled (a);
|
|
|
|
|
|
|
|
Assert.AreEqual (a.Count, 1);
|
|
|
|
Assert.AreEqual (b.Count, 1);
|
|
|
|
|
|
|
|
a.Close ();
|
|
|
|
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 a = new UnixSignal (Signum.SIGINT);
|
|
|
|
UnixSignal b = new UnixSignal (Signum.SIGINT);
|
|
|
|
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
SleepUntilSignaled (a);
|
|
|
|
|
|
|
|
Assert.AreEqual (a.Count, 1);
|
|
|
|
Assert.AreEqual (b.Count, 1);
|
|
|
|
|
|
|
|
b.Close ();
|
|
|
|
a.Reset ();
|
|
|
|
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
SleepUntilSignaled (a);
|
|
|
|
Assert.AreEqual (a.Count, 1);
|
|
|
|
|
|
|
|
a.Close ();
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
2015-08-26 07:17:56 -04:00
|
|
|
[Category ("AndroidNotWorking")] // Android 4.4.4 doesn't have signal(2)
|
2014-08-13 10:39:27 +01:00
|
|
|
public void TestSignalActionInteraction ()
|
|
|
|
{
|
|
|
|
using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
|
|
|
|
Stdlib.SetSignalAction (Signum.SIGINT, SignalAction.Ignore);
|
|
|
|
Stdlib.raise (Signum.SIGINT);
|
|
|
|
Assert.AreEqual (a.Count, 0); // never invoked
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static readonly Signum[] signals = new Signum[] {
|
|
|
|
Signum.SIGHUP, Signum.SIGINT, Signum.SIGTERM, Signum.SIGCONT,
|
|
|
|
};
|
|
|
|
|
|
|
|
const int StormCount = 100000;
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestRaiseStorm ()
|
|
|
|
{
|
|
|
|
UnixSignal[] usignals = CreateSignals (signals);
|
|
|
|
Thread[] threads = new Thread[]{
|
|
|
|
CreateRaiseStormThread (StormCount/4),
|
|
|
|
CreateRaiseStormThread (StormCount/4),
|
|
|
|
CreateRaiseStormThread (StormCount/4),
|
|
|
|
CreateRaiseStormThread (StormCount/4),
|
|
|
|
};
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Start ();
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Join ();
|
2015-10-30 12:42:46 -04:00
|
|
|
AssertCountSet (usignals);
|
2016-04-28 08:44:23 -04:00
|
|
|
// signal delivery might take some time, wait a bit before closing
|
|
|
|
// the UnixSignal so we can ignore it and not terminate the process
|
|
|
|
// when a SIGHUP/SIGTERM arrives afterwards
|
|
|
|
Thread.Sleep (1000);
|
2014-08-13 10:39:27 +01:00
|
|
|
CloseSignals (usignals);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void AssertCount (UnixSignal[] usignals)
|
|
|
|
{
|
|
|
|
int sum = 0;
|
|
|
|
foreach (UnixSignal s in usignals)
|
|
|
|
sum += s.Count;
|
|
|
|
Assert.AreEqual (sum, StormCount);
|
|
|
|
}
|
|
|
|
|
2015-10-30 12:42:46 -04:00
|
|
|
static void AssertCountSet (UnixSignal[] usignals)
|
|
|
|
{
|
|
|
|
foreach (UnixSignal s in usignals) {
|
|
|
|
Assert.IsTrue (s.Count > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
static UnixSignal[] CreateSignals (Signum[] signals)
|
|
|
|
{
|
|
|
|
UnixSignal[] s = new UnixSignal [signals.Length];
|
|
|
|
for (int i = 0; i < signals.Length; ++i)
|
|
|
|
s [i] = new UnixSignal (signals [i]);
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CloseSignals (UnixSignal[] signals)
|
|
|
|
{
|
|
|
|
foreach (UnixSignal s in signals)
|
|
|
|
s.Close ();
|
|
|
|
}
|
|
|
|
|
2016-02-22 11:00:01 -05:00
|
|
|
// Create thread that issues many signals from a set of harmless signals
|
2014-08-13 10:39:27 +01:00
|
|
|
static Thread CreateRaiseStormThread (int max)
|
|
|
|
{
|
|
|
|
return new Thread (delegate () {
|
|
|
|
Random r = new Random (Environment.TickCount);
|
|
|
|
for (int i = 0; i < max; ++i) {
|
|
|
|
int n = r.Next (0, signals.Length);
|
|
|
|
Stdlib.raise (signals [n]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestAddRemove ()
|
|
|
|
{
|
|
|
|
UnixSignal[] usignals = CreateSignals (signals);
|
|
|
|
|
|
|
|
Thread[] threads = new Thread[]{
|
|
|
|
CreateRaiseStormThread (StormCount),
|
|
|
|
CreateSignalCreatorThread (),
|
|
|
|
};
|
|
|
|
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Start ();
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Join ();
|
|
|
|
|
2015-10-30 12:42:46 -04:00
|
|
|
AssertCountSet (usignals);
|
2014-08-13 10:39:27 +01:00
|
|
|
CloseSignals (usignals);
|
|
|
|
}
|
|
|
|
|
2016-02-22 11:00:01 -05:00
|
|
|
// Create thread that repeatedly registers then unregisters signal handlers
|
2014-08-13 10:39:27 +01:00
|
|
|
static Thread CreateSignalCreatorThread ()
|
|
|
|
{
|
|
|
|
return new Thread (delegate () {
|
|
|
|
Random r = new Random (Environment.TickCount << 4);
|
|
|
|
for (int i = 0; i < StormCount; ++i) {
|
|
|
|
int n = r.Next (0, signals.Length);
|
|
|
|
using (new UnixSignal (signals [n]))
|
|
|
|
using (new UnixSignal (signals [(n+1)%signals.Length]))
|
|
|
|
using (new UnixSignal (signals [(n+2)%signals.Length]))
|
|
|
|
using (new UnixSignal (signals [(n+3)%signals.Length])) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestWaitAny ()
|
|
|
|
{
|
|
|
|
UnixSignal[] usignals = CreateSignals (signals);
|
|
|
|
|
|
|
|
Thread[] threads = new Thread[]{
|
|
|
|
CreateRaiseStormThread (StormCount),
|
|
|
|
CreateSignalCreatorThread (),
|
|
|
|
CreateWaitAnyThread (usignals [0], usignals [2]),
|
|
|
|
CreateWaitAnyThread (usignals [1], usignals [3]),
|
|
|
|
CreateWaitAnyThread (usignals [1], usignals [2]),
|
|
|
|
};
|
|
|
|
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Start ();
|
|
|
|
foreach (Thread t in threads)
|
|
|
|
t.Join ();
|
|
|
|
|
2015-10-30 12:42:46 -04:00
|
|
|
AssertCountSet (usignals);
|
2014-08-13 10:39:27 +01:00
|
|
|
CloseSignals (usignals);
|
|
|
|
}
|
|
|
|
|
2016-02-22 11:00:01 -05:00
|
|
|
// Create thread that blocks until at least one of the given signals is received
|
2014-08-13 10:39:27 +01:00
|
|
|
static Thread CreateWaitAnyThread (params UnixSignal[] usignals)
|
|
|
|
{
|
|
|
|
return new Thread (delegate () {
|
|
|
|
int idx = UnixSignal.WaitAny (usignals, 30000);
|
|
|
|
Assert.AreEqual (idx >= 0 && idx < usignals.Length, true);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|