Re: [Mono-dev] signal.c cross-thread access
The test for 64 signals passed to WaitAny, and the bounds check in the WaitAny entry point, is to guard against overrunning the bounds of a new pollfd array of NUM_SIGNALS length: + struct pollfd fd_structs[NUM_SIGNALS]; + if (count NUM_SIGNALS) I don't have an account to commit, so if you could do the honours if you are happy with the bounds check. Cheers -Tim -Original Message- From: Jonathan Pryor [mailto:jonpr...@vt.edu] Sent: 19 February 2009 15:53 To: Tim Jenks Cc: mono-devel-list@lists.ximian.com Subject: Re: [Mono-dev] signal.c cross-thread access It's looking good, just one question remains. On Thu, 2009-02-12 at 14:51 +, tim.je...@realtimeworlds.com wrote: Index: Test/Mono.Unix/UnixSignalTest.cs === --- Test/Mono.Unix/UnixSignalTest.cs(revision 123183) +++ Test/Mono.Unix/UnixSignalTest.cs(working copy) + [Test] + public void TestWaitAnyFailsWithMore64Signals() + { + UnixSignal s1 = new UnixSignal(Signum.SIGINT); + UnixSignal[] signals = new UnixSignal[65]; + for (int i=0; i65; ++i) + signals[i] = s1; + + Assert.That(UnixSignal.WaitAny(signals, new TimeSpan(0,0,1)), Is.EqualTo(-1)); + } Why should this be an error? The no more than 64 UnixSignal instances is a restriction on the number of UnixSignal instances, not the number we can block on... Index: signal.c === --- signal.c(revision 123183) +++ signal.c(working copy) @@ -333,27 +370,32 @@ int Mono_Unix_UnixSignal_WaitAny (void** _signals, int count, int timeout /* milliseconds */) { - fd_set read_fds; - int mr, r; - int max_fd = 0; + int r; + int currfd = 0; + struct pollfd fd_structs[NUM_SIGNALS]; signal_info** signals = (signal_info**) _signals; - mr = pthread_mutex_lock (signals_mutex); - if (mr != 0) { - errno = mr; + if (count NUM_SIGNALS) return -1; Again, I don't understand the need for this check. Otherwise, this is looking good. Do you have an account to commit with, or will I need to do it? Thanks, - Jon This email has been scanned by the MessageLabs Email Security System DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] signal.c cross-thread access
Hi, I was wondering if there was any update on a review for this patch? Cheers -Tim -Original Message- From: mono-devel-list-boun...@lists.ximian.com [mailto:mono-devel-list- boun...@lists.ximian.com] On Behalf Of tim.je...@realtimeworlds.com Sent: 12 February 2009 14:51 To: jonpr...@vt.edu Cc: mono-devel-list@lists.ximian.com Subject: Re: [Mono-dev] signal.c cross-thread access Hi Jon, Here's the changes you suggested. I'm now using poll() rather than select() as discussed on Tuesday. The test reproducing multiple select() on the same fd for the same operation that's working under poll is included in mcs.diff. This is contributed under MIT/X11 Cheers -Tim -Original Message- From: Jonathan Pryor [mailto:jonpr...@vt.edu] Sent: 09 February 2009 14:08 To: Tim Jenks Subject: RE: [Mono-dev] signal.c cross-thread access On Mon, 2009-02-09 at 12:31 +, tim.je...@realtimeworlds.com wrote: Here we can see one select is returning after the first char is sent to the pipe (and reads 1 byte). The second char is then sent to the pipe, but the second select() call does not unblock. I am assuming this is undefined behaviour when multiple threads select() on the same fd for the same operation, although I cannot find any documentation proving this. Having looked at epoll, this appears to be addressed. Is there any other mechanism? epoll(2) doesn't seem to be supported on Mac OS X (at least, it's not listed at [0]). Would poll(2) work? - Jon [0] http://developer.apple.com/documentation/Darwin/Reference/ManPages/ This email has been scanned by the MessageLabs Email Security System DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. This email has been scanned by the MessageLabs Email Security System DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] signal.c cross-thread access
Hi Jon, Here's the changes you suggested. I'm now using poll() rather than select() as discussed on Tuesday. The test reproducing multiple select() on the same fd for the same operation that's working under poll is included in mcs.diff. This is contributed under MIT/X11 Cheers -Tim -Original Message- From: Jonathan Pryor [mailto:jonpr...@vt.edu] Sent: 09 February 2009 14:08 To: Tim Jenks Subject: RE: [Mono-dev] signal.c cross-thread access On Mon, 2009-02-09 at 12:31 +, tim.je...@realtimeworlds.com wrote: Here we can see one select is returning after the first char is sent to the pipe (and reads 1 byte). The second char is then sent to the pipe, but the second select() call does not unblock. I am assuming this is undefined behaviour when multiple threads select() on the same fd for the same operation, although I cannot find any documentation proving this. Having looked at epoll, this appears to be addressed. Is there any other mechanism? epoll(2) doesn't seem to be supported on Mac OS X (at least, it's not listed at [0]). Would poll(2) work? - Jon [0] http://developer.apple.com/documentation/Darwin/Reference/ManPages/ This email has been scanned by the MessageLabs Email Security System DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. mcs.diff Description: mcs.diff signal.c.diff Description: signal.c.diff ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] signal.c cross-thread access
Hi Jon List, Here's another take at this implemented as you suggested. Couple of questions though: 1. Somehow find out which is preferable for normal UnixSignal usage: a. One pipe/UnixSignal instance for the lifetime of the UnixSignal. b. One pipe/UnixSignal instance for the lifetime of a WaitAny() call. I'm assuming normal is that a UnixSignal will last for the life of the application; that is, UnixSignal instances won't be short lived. Meanwhile, I'd expect WaitAny() to be comparatively infrequent, but have less clues about how it's used in practice. We're using SIGRT* raised a bunch of times a second for the update tick of a game server, I'm talking 20-30Hz. For our use case I think a) is preferable, though I've implemented this as b) as suggested just now. What are your thoughts? You might need to change wait_for_any() to actually perform error checking on the read(h-read_fd, c, 1) call, as this could now error if multiple threads are calling WaitAny(). What kind of error conditions are you expecting in this instance? And finally, here's some comments on mph_int*: Obviously the signal handler can be executing concurrently with the other functions in signal.c that are guarded by the mutex; to keep a consistent view of pipecnt in the signal handler I have used atomics: 1. There does not appear to be an equivalent to InterlockedIncrement in the glib functions (returning the value after atomic inc), so there is code in setup_pipes that would race if it were re-entrant. It isn't re-entrant due to the global mutex being held but this needs tidying to avoid confusion. Effectively, I need to: if (InterlockedIncrement(pipecnt) == 1) { setup pipes }. 2. Conversely, I needed an atomic decrement. Having looked at the glib functions I could only find g_atomic_int_dec_and_test in 2.4. Is this OK, or is there an a g_atomic_int_dec ? This is to achieve: if (InterlockedDecrement(pipecnt) == 0) { teardown pipes }. g_atomic_int_dec_and_test clearly does the job, but it's a little inconsistent with InterlockedDecrement with respect to the mph_int* macros. Cheers -Tim DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. signal.c.diff Description: signal.c.diff UnixSignal.cs.diff Description: UnixSignal.cs.diff ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] signal.c cross-thread access
Hi, Attached is a patch to signal.c supporting cross-thread access. Currently signal.c maintains a coarse grained mutex in each entry point from managed code, including the blocking WaitAny call. This makes the use of the UnixSignal* code limited at best - one thread may be sat in a WaitAny for an undetermined period of time, blocking access to any other managed thread wishing to use the signalling code. This patch provides fine grained locking of the relevant singal_info struct, and a removal of the coarse grained mutex, allowing multiple threads to interact with the native signal code. -Tim DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. signal.c.diff Description: signal.c.diff UnixSignal.cs.diff Description: UnixSignal.cs.diff ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] FW: RealTimeSignal patch
Further updates to patch based on comments. 1. Formatting. There are still numerous cases where there isn't a space before the opening parenthesis. My bad here, I was not familiar with the Mono Coding Guidelines, and I had misunderstood your previous comments re: spacing before parenthesis. This should now be fixed up. 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. I don't have commit access no :) + 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. I think we're OK with this one; from http://msdn.microsoft.com/en-us/library/aa645757(VS.71).aspx: `Thus, when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order.' Cheers -Tim DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. mcs.diff Description: mcs.diff mono.diff Description: mono.diff ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] FW: RealTimeSignal patch
Thanks Jon, Attached is another pass at this. Just one point below that I couldn't address as suggested: +#if NET_2_0 +: IEquatable RealTimeSignum +#endif + { + private int rt_offset; + public static readonly RealTimeSignum MinValue = new RealTimeSignum(0); + public static readonly RealTimeSignum MaxValue = new RealTimeSignum(UnixSignal.GetSIGRTMAX() - UnixSignal.GetSIGRTMIN() - 1); + + public RealTimeSignum(int offset) + { + if (offset 0) + throw new ArgumentOutOfRangeException(Offset cannot be negative); + if (offset (UnixSignal.GetSIGRTMAX()- UnixSignal.GetSIGRTMIN()-1)) There's no need to call UnixSignal.GetSIGRTMAX() here, as the MaxValue field has already computed this. Just do: if (offset MaxValue.Offset) throw new ArgumentOutOfRangeException(...); Problem here is that MaxValue is dependent on this cstor. When constructing the MaxValue field, MaxValue.Offset will be 0 in the case above. For now, I've refactored the logic to a private static readonly int MaxOffset, I hope this is sufficient and removes the duplication in question. Cheers -Tim DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ. mcs.diff Description: mcs.diff mono.diff Description: mono.diff ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] FW: RealTimeSignal patch
Hi List Jon, The attached patches to the class libraries (Mono.Posix) native posix support code (signal.c) provides support for handling SIGRT* signals in the Mono.Posix libraries, specifically: * A RealTimeSignum struct for representing realtime signals, providing an offset to SIGRTMIN ** MinValue and MaxValue provide the minimum and maximum signal values (SIGRTMIN and SIGRTMAX) * NativeConvert static methods provide: ** Conversion between an offset to SIGRTMIN and a RealTimeSignum ** Conversion between a RealTimeSignum and a platform specific SIGRT* signal number * A new UnixSignal constructor overload for handling RealTimeSignum ** Added new IsRealTimeSignal property to indicate whether a UnixSignal represents a realtime signal * Stdlib.raise and Stdlib.SetSigAction overloads for RealTimeSignum I've also addressed Jon's comments in this second pass today which were from a discussion off-list. Quoted is snippets of yesterdays patch for reference :) Cheers -Tim -Original Message- From: Jonathan Pryor [mailto:jonpr...@vt.edu] Sent: 15 December 2008 21:25 To: Tim Jenks Subject: Re: RealTimeSignal patch Offhand, which is better: RealTimeSignal or RealTimeSignum? Given that it's effectively a variant of the Signum values, I think the latter may be better... Also, you should post follow ups to mono-devel-list. On Mon, 2008-12-15 at 14:10 +, tim.je...@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) @@ -531,9 +541,20 @@ public static int raise (Signum sig) { int _sig = NativeConvert.FromSignum (sig); - return sys_raise (_sig); + return raise(_sig); } + public static int raise (RealTimeSignal rts) + { + int _sig = NativeConvert.FromRealTimeSignal(rts); + return raise(_sig); + } + + private static int raise(int signum) + { + return sys_raise(signum); + } Remove the raise(int) overload, and just have raise(Signum) and raise(RealTimeSignal) call sys_raise() directly. 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,18 @@ // Non-generated exports // + [DllImport (LIB, EntryPoint=Mono_Posix_FromRealTimeSignal)] +private static extern int FromRealTimeSignal (Int32 offset, out Int32 rval); `private` should line up with the [DllImport] on the previous line. + + // convert a realtime signal to os signal + public static int FromRealTimeSignal(RealTimeSignal sig) + { + int sigNum; + if (FromRealTimeSignal(sig.Offset, out sigNum) == -1) + ThrowArgumentException(sig.Offset); + return sigNum; + } + Should we also provide a NativeConvert.ToRealTimeSignal(int) method? It would merely call the RealTimeSignal constructor, but it may make members easier to find. Index: class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs === --- class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs (revision 121281) +++ class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs (working copy) @@ -3,11 +3,13 @@ // // Authors: // Jonathan Pryor jonpr...@vt.edu +// Tim Jenks tim.je...@realtimeworlds.com // // (C) 2008 Jonathan Pryor // using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; using System; using System.Text; using System.Threading; @@ -18,7 +20,88 @@ [TestFixture] public class UnixSignalTest { + [Test] + public void TestRealTimeCstor() + { + RealTimeSignal rts = new RealTimeSignal(0); + using (UnixSignal s = new UnixSignal(rts)) + { + Assert.That(s.RealTimeSignal, Is.EqualTo(rts)); + } + } + + [Test] + [ExpectedException] + public void TestRealTimeOutOfRange() + { + RealTimeSignal rts = new RealTimeSignal(int.MaxValue); + using (UnixSignal s = new UnixSignal(rts)) + { + }
[Mono-list] Handling SIGRT* signals
Hi List, I have been looking over the UnixSignal class hoping to Wait on a SIGRT signal raised by a native library. Unfortunately, I can only create UnixSignal instances to handle signals defined in the Signum enumerator and not Signals = SIGRTMIN. Is there a way to handle SIGRT* signals in Mono currently? Cheers -Tim DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ.___ Mono-list maillist - Mono-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-list
[Mono-list] Mono ASP.NET Webservice
Hi List, I am currently investigating the best approach for deploying an persistent ASP.NET Webservice (.asmx) under Linux/Mono. This is a SOAP ASP.NET Webservice that must run over SSL. I have tried the following: * Apache2/mod_mono, configured using using mono-server2. Using AutoHosting. (Apache/2.2.8 (Ubuntu) mod_mono/1.9 mod_ssl/2.2.8 OpenSSL/0.9.8g Server at timjenks2 Port 443). This is functional, and I can call WebMethods fine. One gotcha was that the application lifetime method Application_Start does not get called, some refactoring to a stateless service was needed to get everything running. * Lighttpd/fastcgi-mono-server2. This serves the .asmx OK when browsing, but upon making SOAP calls to the WebMethod, the server 404s (see below). I am assuming this is just misconfiguration of either fastcgi-mono-server2 or lighttpd, but any hints would be appreciated. Does anyone have any recommendations for the best approach for deploying ASP.NET Webservices under Mono? Reading material seems to be lacking, so any advice would be outstanding. Secondly, are stateful ASP.NET Applications ala IIS supported (i.e. the service lifetime methods Application_Start/End are called, and the state of the service is maintained between calls)? If so, does anyone have pointers as to configuration settings under either Lighty or mod_mono? (I've done the usual trawling, but have failed to turn up anything concrete). Thanks in advance Tim Jenks Software Engineer Realtime Worlds Ltd 404 SOAP call under Lighttpd: The remote server returned an error: (404) Not Found. ?xml version=1.0 ? !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd;html xmlns=http://www.w3.org/1999/xhtml; xml:lang=en lang=enheadtitleError 404/titlestyle type=text/cssbody {font-family:Verdana,DejaVu Sans, sans-serif;font-weight:normal;font-size: .7em;color:black;background-color: white} p {font-family:Verdana,DejaVu Sans,sans-serif;font-weight:normal;color:black;margin-top: -5px} b {font-family:Verdana,DejaVu Sans,sans-serif;font-weight:bold;color:black;margin-top: -5px} h1 { font-family:Verdana,DejaVu Sans,sans-serif;font-weight:normal;font-size:18pt;color:red } h2 { font-family:Verdana,DejaVu Sans, sans-serif;font-weight:normal;font-size:14pt;color:maroon } pre {font-family:Lucida Console,DejaVu Sans Mono,monospace;font-size: 0.9em} div.bodyText {font-family: Verdana,DejaVu Sans,sans-serif} table.sampleCode 100%; background-color: #cc; .errorText red; font-weight: bold .marker {font-weight: bold; color: black;text-decoration: none;} .version gray; .error {margin-bottom: 10px;} .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }/style/headbodyh1Server Error in '/authWS' Application/h1hr style=color: silver/h2emThe resource cannot be found./em/h2 pstrongDescription: /strongHTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly./p pstrongResource URL: /strong/authWS/Gateway.asmx/Admin_Test/p hr style=color: silver/strongVersion information: /strong Mono Version: 2.0.50727.42; ASP.NET Version: 2.0.50727.42/body/html !-- [System.Web.HttpException]: Path '/authWS/Gateway.asmx/Admin_Test' was not found. at System.Web.StaticFileHandler.ProcessRequest (System.Web.HttpContext context) [0x0] at System.Web.HttpApplication+c__CompilerGenerated2.MoveNext () [0x0] at System.Web.HttpApplication.Tick () [0x0] -- DISCLAIMER This message and any attachments contain privileged and confidential information intended for the use of the addressee named above. If you are not the intended recipient of this message, you are hereby notified that any use, dissemination, distribution or reproduction of this message is prohibited. Please note that we cannot guarantee that this message or any attachment is virus free or that it has not been intercepted and amended. The views of the author may not necessarily reflect those of Realtime Worlds Ltd. Realtime Worlds Ltd is registered in Scotland, number 225628. Registered Office: 152 West Marketgait, Dundee, DD1 1NJ.___ Mono-list maillist - Mono-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-list