[Mono-dev] FW: RealTimeSignal patch
Jonathan Pryor
jonpryor at vt.edu
Wed Dec 17 13:05:20 EST 2008
Looking good, but three issues need fixing before we can commit:
1. Formatting. There are still numerous cases where there isn't a space
before the opening parenthesis.
2. UnixSignal tests that use RealTimeSignum should remain in the
UnixSignalTest class, as these are still testing UnixSignal
functionality, not RealTimeSignum functionality.
3. mono/support/map.h needs to be updated to provide prototypes for the
new functions in mono/support/signal.c. Installing mono-tools (to get
create-native-map) and running `make refresh` from mono/support will
update mono/support/map.h for you.
BTW, do you have commit access to svn? If not, I can handle (3) for you
when I commit the patches.
- Jon
On Wed, 2008-12-17 at 11:19 +0000, tim.jenks at realtimeworlds.com wrote:
> Index: class/Mono.Posix/Mono.Unix.Native/Stdlib.cs
> ===================================================================
> --- class/Mono.Posix/Mono.Unix.Native/Stdlib.cs (revision 121281)
> +++ class/Mono.Posix/Mono.Unix.Native/Stdlib.cs (working copy)
> @@ -504,6 +504,16 @@
>
> public static int SetSignalAction (Signum signal, SignalAction action)
> {
> + return SetSignalAction(NativeConvert.FromSignum(signal), action);
Missing space before opening parenthesis (2x).
> + }
> +
> + public static int SetSignalAction (RealTimeSignum rts, SignalAction action)
> + {
> + return SetSignalAction(NativeConvert.FromRealTimeSignum(rts), action);
Missing space before opening parenthesis (2x).
> + }
> +
> + private static int SetSignalAction (int signum, SignalAction action)
> + {
> IntPtr handler = IntPtr.Zero;
> switch (action) {
> case SignalAction.Default:
> @@ -518,7 +528,7 @@
> default:
> throw new ArgumentException ("Invalid action value.", "action");
> }
> - IntPtr r = sys_signal (NativeConvert.FromSignum (signal), handler);
> + IntPtr r = sys_signal (signum, handler);
> if (r == _SIG_ERR)
> return -1;
> return 0;
> @@ -530,10 +540,14 @@
> [CLSCompliant (false)]
> public static int raise (Signum sig)
> {
> - int _sig = NativeConvert.FromSignum (sig);
> - return sys_raise (_sig);
> + return sys_raise(NativeConvert.FromSignum(sig));
Missing space before opening parenthesis.
> }
>
> + public static int raise(RealTimeSignum rts)
> + {
> + return sys_raise(NativeConvert.FromRealTimeSignum(rts));
Missing space before opening parenthesis (2x).
> + }
> +
> //
> // <stdio.h> -- COMPLETE except for :
> // - the scanf(3) family .
> Index: class/Mono.Posix/Mono.Unix.Native/RealTimeSignum.cs
> ===================================================================
> --- class/Mono.Posix/Mono.Unix.Native/RealTimeSignum.cs (revision 0)
> +++ class/Mono.Posix/Mono.Unix.Native/RealTimeSignum.cs (revision 0)
> @@ -0,0 +1,83 @@
> +//
> +// Authors:
> +// Tim Jenks (tim.jenks at realtimeworlds.com)
> +//
> +// (C) 2008 Realtime Worlds Ltd
> +//
> +// Permission is hereby granted, free of charge, to any person obtaining
> +// a copy of this software and associated documentation files (the
> +// "Software"), to deal in the Software without restriction, including
> +// without limitation the rights to use, copy, modify, merge, publish,
> +// distribute, sublicense, and/or sell copies of the Software, and to
> +// permit persons to whom the Software is furnished to do so, subject to
> +// the following conditions:
> +//
> +// The above copyright notice and this permission notice shall be
> +// included in all copies or substantial portions of the Software.
> +//
> +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
> +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
> +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
> +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> +//
> +
> +using System;
> +using System.Runtime.InteropServices;
> +using System.Threading;
> +
> +namespace Mono.Unix.Native {
> +
> + public struct RealTimeSignum
> +#if NET_2_0
> + : IEquatable <RealTimeSignum>
> +#endif
> + {
> + private int rt_offset;
> + private static readonly int MaxOffset = UnixSignal.GetSIGRTMAX()-UnixSignal.GetSIGRTMIN()-1;
> + public static readonly RealTimeSignum MinValue = new RealTimeSignum(0);
> + public static readonly RealTimeSignum MaxValue = new RealTimeSignum(MaxOffset);
Missing space before opening parenthesis.
Offhand, does C# guarantee the order of initialization of members? I
don't remember, and if the order isn't guaranteed then we'll need to use
a static constructor to ensure that MaxOffset is set before setting
MaxValue.
> + public RealTimeSignum(int offset)
Missing space before opening parenthesis.
> + {
> + if (offset < 0)
> + throw new ArgumentOutOfRangeException("Offset cannot be negative");
Missing space before opening parenthesis.
> + if (offset > MaxOffset)
> + throw new ArgumentOutOfRangeException("Offset greater than maximum supported SIGRT");
Missing space before opening parenthesis.
> + rt_offset = offset;
> + }
> +
> + public int Offset {
> + get { return rt_offset; }
> + }
> +
> + public override int GetHashCode()
Missing space before opening parenthesis.
I'll stop mentioning these, but there are lots of such spots...
> + {
> + return rt_offset.GetHashCode();
> + }
> +
> + public override bool Equals(object obj)
> + {
> + if ((obj == null) || (obj.GetType() != GetType()))
> + return false;
> + return Equals((RealTimeSignum)obj);
> + }
> +
> + public bool Equals(RealTimeSignum value)
> + {
> + return Offset == value.Offset;
> + }
> +
> + public static bool operator==(RealTimeSignum lhs, RealTimeSignum rhs)
> + {
> + return lhs.Equals(rhs);
> + }
> +
> + public static bool operator!=(RealTimeSignum lhs, RealTimeSignum rhs)
> + {
> + return !lhs.Equals(rhs);
> + }
> + }
> +}
> Index: class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs
> ===================================================================
> --- class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs (revision 121281)
> +++ class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs (working copy)
> @@ -18,6 +18,24 @@
> // Non-generated exports
> //
>
> + [DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")]
> + private static extern int FromRealTimeSignum(Int32 offset, out Int32 rval);
> +
> + // convert a realtime signal to os signal
> + public static int FromRealTimeSignum(RealTimeSignum sig)
> + {
> + int sigNum;
> + if (FromRealTimeSignum(sig.Offset, out sigNum) == -1)
> + ThrowArgumentException(sig.Offset);
> + return sigNum;
> + }
> +
> + // convert an offset to an rt signum
> + public static RealTimeSignum ToRealTimeSignum(int offset)
> + {
> + return new RealTimeSignum(offset);
> + }
> +
> // convert from octal representation.
> public static FilePermissions FromOctalPermissionString (string value)
> {
> Index: class/Mono.Posix/Test/Mono.Unix.Native/RealTimeSignumTests.cs
> ===================================================================
> --- class/Mono.Posix/Test/Mono.Unix.Native/RealTimeSignumTests.cs (revision 0)
> +++ class/Mono.Posix/Test/Mono.Unix.Native/RealTimeSignumTests.cs (revision 0)
> @@ -0,0 +1,180 @@
> +//
> +// RealTimeSignumTests.cs - NUnit Test Cases for Mono.Unix.Native.RealTimeSignum
> +//
> +// Authors:
> +// Tim Jenks <tim.jenks at realtimeworlds.com>
> +//
> +// (C) 2008 Realtime Worlds Ltd
> +//
> +
> +using NUnit.Framework;
> +using NUnit.Framework.SyntaxHelpers;
> +using System;
> +using System.Text;
> +using System.Threading;
> +using Mono.Unix;
> +using Mono.Unix.Native;
> +
> +namespace MonoTests.Mono.Unix.Native {
> +
> + [TestFixture]
> + public class RealTimeSignumTest
> + {
> +
> + [Test]
> + 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));
> + }
This is really testing the UnixSignal constructor, so move this test
into UnixSignalTest.
> + }
> +
> + [Test]
> + [ExpectedException(typeof(ArgumentOutOfRangeException))]
> + public void TestRealTimeOutOfRange()
> + {
> + RealTimeSignum rts = new RealTimeSignum(int.MaxValue);
> + }
> +
CreateWaitSignalThread() and MultiThreadTest() should be moved to
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]
> + [ExpectedException(typeof(ArgumentOutOfRangeException))]
> + public void TestRealTimeSignumNegativeOffset()
> + {
> + RealTimeSignum rts1 = new RealTimeSignum(-1);
> + }
> +
> + [Test]
> + public void TestRTSignalEquality()
> + {
> + RealTimeSignum rts1 = new RealTimeSignum(0);
> + RealTimeSignum rts2 = new RealTimeSignum(0);
> + Assert.That(rts1 == rts2, Is.True);
> + Assert.That(rts1 != rts2, Is.False);
> + }
> +
> + [Test]
> + public void TestRTSignalInequality()
> + {
> + RealTimeSignum rts1 = new RealTimeSignum(0);
> + RealTimeSignum rts2 = new RealTimeSignum(1);
> + Assert.That(rts1 == rts2, Is.False);
> + Assert.That(rts1 != rts2, Is.True);
> + }
> +
> + [Test]
> + public void TestRTSignalGetHashCodeEquality()
> + {
> + RealTimeSignum rts1 = new RealTimeSignum(0);
> + RealTimeSignum rts2 = new RealTimeSignum(0);
> + Assert.That(rts1.GetHashCode(), Is.EqualTo(rts2.GetHashCode()));
> + }
> +
> + [Test]
> + public void TestRTSignalGetHashCodeInequality()
> + {
> + RealTimeSignum rts1 = new RealTimeSignum(0);
> + RealTimeSignum rts2 = new RealTimeSignum(1);
> + Assert.That(rts1.GetHashCode(), Is.Not.EqualTo(rts2.GetHashCode()));
> + }
> +
> + [Test]
> + public void TestIsRTSignalPropertyForRTSignum()
> + {
> + UnixSignal signal1 = new UnixSignal(new RealTimeSignum(0));
> + Assert.That(signal1.IsRealTimeSignal, Is.True);
> + }
> +
> + [Test]
> + public void TestIsRTSignalPropertyForSignum()
> + {
> + UnixSignal signal1 = new UnixSignal(Signum.SIGSEGV);
> + Assert.That(signal1.IsRealTimeSignal, Is.False);
> + }
> +
> + [Test]
> + public void TestSignumProperty()
> + {
> + UnixSignal signal1 = new UnixSignal(Signum.SIGSEGV);
> + Assert.That(signal1.Signum, Is.EqualTo(Signum.SIGSEGV));
> + }
> +
> + [Test]
> + [ExpectedException]
> + public void TestSignumPropertyThrows()
> + {
> + UnixSignal signal1 = new UnixSignal(new RealTimeSignum(0));
> + Signum s = signal1.Signum;
This should be in UnixSignalTest.
> + }
> +
> + [Test]
> + public void TestRealTimeSignumProperty()
> + {
> + RealTimeSignum rts = new RealTimeSignum(0);
> + UnixSignal signal1 = new UnixSignal(rts);
> + Assert.That(signal1.RealTimeSignum, Is.EqualTo(rts));
This should be in UnixSignalTest.
> + }
> +
> + [Test]
> + [ExpectedException]
> + public void TestRealTimePropertyThrows()
> + {
> + UnixSignal signal1 = new UnixSignal(Signum.SIGSEGV);
> + RealTimeSignum s = signal1.RealTimeSignum;
This should be in UnixSignalTest.
> + }
> +
> + [Test]
> + public void TestRaiseRTMINSignal()
> + {
> + RealTimeSignum rts = new RealTimeSignum(0);
> + using (UnixSignal signal = new UnixSignal(rts))
> + {
> + MultiThreadTest(signal, 5000, delegate() {
> + Thread.Sleep(1000);
> + Stdlib.raise(rts);
> + });
This should be in UnixSignalTest.
> + }
> + }
> +
> + [Test]
> + public void TestRaiseRTMINPlusOneSignal()
> + {
> + RealTimeSignum rts = new RealTimeSignum(1);
> + using (UnixSignal signal = new UnixSignal(rts))
> + {
> + MultiThreadTest(signal, 5000, delegate() {
> + Thread.Sleep(1000);
> + Stdlib.raise(rts);
> + });
This should be in UnixSignalTest.
> + }
> + }
> + }
> +}
> Index: class/Mono.Posix/Mono.Posix_test.dll.sources
> ===================================================================
> --- class/Mono.Posix/Mono.Posix_test.dll.sources (revision 121281)
> +++ class/Mono.Posix/Mono.Posix_test.dll.sources (working copy)
> @@ -5,4 +5,5 @@
> Mono.Unix/UnixPathTest.cs
> Mono.Unix/UnixSignalTest.cs
> Mono.Unix/UnixUserTest.cs
> +Mono.Unix.Native/RealTimeSignumTests.cs
> Mono.Unix.Native/StdlibTest.cs
> Index: class/Mono.Posix/Mono.Posix.dll.sources
> ===================================================================
> --- class/Mono.Posix/Mono.Posix.dll.sources (revision 121281)
> +++ class/Mono.Posix/Mono.Posix.dll.sources (working copy)
> @@ -34,6 +34,7 @@
> ./Mono.Unix.Native/MapAttribute.cs
> ./Mono.Unix.Native/NativeConvert.cs
> ./Mono.Unix.Native/NativeConvert.generated.cs
> +./Mono.Unix.Native/RealTimeSignum.cs
> ./Mono.Unix.Native/Stdlib.cs
> ./Mono.Unix.Native/Syscall.cs
> ./Mono.Unix.Native/TypeAttributes.cs
> Index: class/Mono.Posix/Mono.Unix/UnixSignal.cs
> ===================================================================
> --- class/Mono.Posix/Mono.Unix/UnixSignal.cs (revision 121281)
> +++ class/Mono.Posix/Mono.Unix/UnixSignal.cs (working copy)
> @@ -3,6 +3,7 @@
> //
> // Authors:
> // Jonathan Pryor (jpryor at novell.com)
> +// Tim Jenks (tim.jenks at realtimeworlds.com)
> //
> // (C) 2008 Novell, Inc.
> //
> @@ -33,28 +34,55 @@
> using Mono.Unix.Native;
>
> namespace Mono.Unix {
> +
> public class UnixSignal : WaitHandle {
> - private Signum signum;
> + private int signum;
> private IntPtr signal_info;
>
> public UnixSignal (Signum signum)
> {
> - this.signum = signum;
> - // ensure signum is a valid signal
> - int _signum = NativeConvert.FromSignum (signum);
> - this.signal_info = install (_signum);
> + this.signum = NativeConvert.FromSignum(signum);
> + this.signal_info = install(this.signum);
> if (this.signal_info == IntPtr.Zero) {
> - throw new ArgumentException ("Unable to handle signal", "signum");
> + throw new ArgumentException("Unable to handle signal", "signum");
> }
> }
>
> + public UnixSignal (Mono.Unix.Native.RealTimeSignum rtsig)
> + {
> + signum = NativeConvert.FromRealTimeSignum(rtsig);
> + this.signal_info = install(this.signum);
Why is there a space before `this' on this line?
> + if (this.signal_info == IntPtr.Zero) {
> + throw new ArgumentException("Unable to handle signal", "signum");
> + }
> + }
> +
> public Signum Signum {
> get {
> + if (IsRealTimeSignal)
> + throw new InvalidOperationException("This signal is a RealTimeSignum");
> AssertValid ();
Remove the AssertValid call, and add it to IsRealTimeSignal.
> - return signum;
> + return NativeConvert.ToSignum(signum);
> }
> }
>
> + public RealTimeSignum RealTimeSignum {
> + get {
> + if (!IsRealTimeSignal)
> + throw new InvalidOperationException("This signal is not a RealTimeSignum");
> + return NativeConvert.ToRealTimeSignum(signum-GetSIGRTMIN());
> + }
> + }
> +
> + public bool IsRealTimeSignal {
> + get {
Add an AssertValid(); call here.
> + int sigrtmin = GetSIGRTMIN();
> + if (sigrtmin == -1)
> + return false;
> + return signum >= sigrtmin;
> + }
> + }
> +
> [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
> EntryPoint="Mono_Unix_UnixSignal_install")]
> private static extern IntPtr install (int signum);
> @@ -67,6 +95,14 @@
> EntryPoint="Mono_Unix_UnixSignal_WaitAny")]
> private static extern int WaitAny (IntPtr[] infos, int count, int timeout);
>
> + [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
> + EntryPoint="Mono_Posix_SIGRTMIN")]
> + internal static extern int GetSIGRTMIN();
> +
> + [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
> + EntryPoint="Mono_Posix_SIGRTMAX")]
> + internal static extern int GetSIGRTMAX();
> +
> private void AssertValid ()
> {
> if (signal_info == IntPtr.Zero)
>
More information about the Mono-devel-list
mailing list