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] [PATCH] TcpChannel hang on Windows.
Hi, I've modified the test case to call QueueUserAPC. And both MS.NET and Mono (without your patch) seems to process the APC. This still makes me think that the difference is in killing threads rather than in Socket implementation. When I uncommented thread.Abort(), both runtimes terminated the thread, but MS.NET prints New thread state: Stopped while Mono prints New thread state: Stopped, AbortRequested that may be the source of bugs. Kornél Bill Holmes wrote: Kornél, I tested your case and it appears to work fine with my changes. I believe that this is because I check for the ThreadState_StopRequested state. I do not check for ThreadState_AbortRequested. That is intentional because that is the behavior I observed with MS .net. Also if I understand it correctly mono_thread_manage wait on all non background threads to complete before it sets the ThreadState_StopRequested on the background threads only and waits for those. I also toggled the background flag in you example to ensure the two runtimes behave the same. Thanks so much for your review! -bill For those interested this is the case I am attempting to fix... static void Main (string[] args) { TcpChannel tc = new TcpChannel (0); } using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Runtime.InteropServices; namespace BlockingAccept { class BlockingAccept { static Socket socket; static IntPtr threadHandle; delegate void APCProc(IntPtr dwParam); [DllImport(kernel32.dll)] static extern uint QueueUserAPC(APCProc pfnAPC, IntPtr hThread, IntPtr dwData); [DllImport(kernel32.dll)] static extern IntPtr GetCurrentThread(); [DllImport(kernel32.dll)] extern static IntPtr GetCurrentProcess(); [DllImport(kernel32.dll)] extern static bool DuplicateHandle(IntPtr sourceProcessHandle, IntPtr sourceHandle, IntPtr targetProcessHandle, out IntPtr targetHandle, uint desiredAccess, bool inheritHandle, uint dwOptions); [DllImport(kernel32.dll)] extern static bool CloseHandle(IntPtr handle); static void Main(string[] args) { Thread.BeginThreadAffinity(); Console.WriteLine(Main thread: + AppDomain.GetCurrentThreadId()); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Blocking = true; socket.Bind(new IPEndPoint(IPAddress.Loopback, 12345)); socket.Listen(1); Thread thread = new Thread(AcceptSocket); //thread.IsBackground = true; thread.Start(); Thread.Sleep(1000); //Console.WriteLine(before Abort); //thread.Abort(); //Console.WriteLine(after Abort); //Thread.Sleep(1000); Console.WriteLine(New thread state: + thread.ThreadState.ToString()); QueueUserAPC(APCCallback, threadHandle, IntPtr.Zero); CloseHandle(threadHandle); Thread.Sleep(1000); Console.WriteLine(New thread state: + thread.ThreadState.ToString()); Thread.EndThreadAffinity(); } static void APCCallback(IntPtr dwParam) { Console.WriteLine(APCCallback thread: + AppDomain.GetCurrentThreadId()); } static void AcceptSocket() { Thread.BeginThreadAffinity(); Console.WriteLine(New thread: + AppDomain.GetCurrentThreadId()); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), out threadHandle, 0, false, 2); Console.WriteLine(before Accept); Socket conn = socket.Accept(); Console.WriteLine(after Accept); conn.Close(); Thread.EndThreadAffinity(); } } } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono svn and ppc
Am 19.12.2008 um 03:27 schrieb Steven Munroe: Paul wrote: Is mono svn working yet with ppc (not ppc64)? I had to disable it for fedora rawhide as there is a signing problem on PPC which looks to have come from a revision at 121203. found the bug. The update to mini-ppc.c (emit_memcpy) replaced ppc_lwzu macro with ppc_load_reg_update, but the definition of ppc_load_reg_update for PPC32 in ppc-codegen.h did not account for reorders parms (ppc_lwz (c, Rd, d, Ra) vs lwzu (c, Rd, Ra, d)). That's odd. In my Git tree I was able to bootstrap ppc32 on OSX and Fedora with my macros, no signing issues. I had notified Mark that some macros were not committed to SVN in their final MIT-licensed form (e.g., ppc_ld/std with ugly ds field), but I didn't have time to look into it since then. As for the argument order, I originally had the new macros with instruction field order and then in the non-indented version fixed them to reflect assembler field order, as was done for most other macros. At least one existing but unused macro was wrong in that aspect and fixed in my tree. For compatibility, I think it's best to keep/use assembler argument order for instruction macros to allow interchange with real assembler code. The meta-macros are up to us but were intended as drop-in replacements for the 32-bit macros. Andreas Net: ppc_lwz is in assembler operand order while ppc_lwzu is instuction field order. The lhzu, lhau, lha, lbzu follow the lwzu form. The rest of the loads and stores follow the ppc_pwz form. In the long run we should make these consistent but in the short term the attached patch will get the PPC32 mono build working again. diff -urN mono-svn-20081216/mono/mono/arch/ppc/ppc-codegen.h mono- svn64/mono/mono/arch/ppc/ppc-codegen.h --- mono-svn-20081216/mono/mono/arch/ppc/ppc-codegen.h2008-12-16 10:45:37.0 -0600 +++ mono-svn64/mono/mono/arch/ppc/ppc-codegen.h 2008-12-18 19:41:31.0 -0600 @@ -150,7 +150,7 @@ #define ppc_load_func(c,D,V)ppc_load_sequence ((c), (D), (V)) #define ppc_load_reg(c,D,d,A) ppc_lwz ((c), (D), (d), (A)) -#define ppc_load_reg_update(c,D,d,A) ppc_lwzu ((c), (D), (d), (A)) +#define ppc_load_reg_update(c,D,d,A) ppc_lwzu ((c), (D), (A), (d)) #define ppc_load_reg_indexed(c,D,A,B)ppc_lwzx ((c), (D), (A), (B)) #define ppc_load_reg_update_indexed(c,D,A,B) ppc_lwzux ((c), (D), (A), (B)) #define ppc_load_multiple_regs(c,D,A,d) ppc_lmw ((c), (D), (A), (d)) ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] More complete PerformanceCounter implementation
On Fri, Dec 19, 2008 at 7:48 AM, Christian Prochnow cpr...@seculogix.dewrote: Dear mono developers, is there any interest in a more complete PerformanceCounter implementation ? I would like to implement the following features: - Process shared performance counters We already have the machinery to share a process performance counters. What we lack is proper tooling around it. - Emulation of standard Windows performance counters - Custom performance counters Feel free to code them up and submit patches. Thanks for your interest in contributing. Rodrigo ___ 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
Thank you for the patches. This has been committed in revisions r121851 and r121852. - Jon ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
Kornél, I do not understand what you example shows. I can understand the thread state problems. Is that all? Are you suggesting that I add to my patch to fix the state problem? Are you suggesting that the socket implementation is fine in svn and we need to address the abort/stop thread in a more general manner? Do you have any suggestions? What I do know is background threads that are blocked are causing mono to hang on exit. Foreground threads that are blocked should cause the process to hang on exit as that is how MS .Net behaves. Do you feel that we should not wait on background threads on exit, but simply kill them? I know it is a lot of questions but I am not certain of the direction you are trying to point me. This is a bug that I REALLY need fixed now. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
Kornél, After reading your mail a bunch more times and messing with the sample I think I finally get what you were saying. What I discovered was that the APC callback being a managed method gives mono a chance to check the thread state when crossing to and from the managed thread boundary. It is not the fact that you called an APC that was important. What is important is that the APC was a managed call. This does in fact give me some ideas on new things to try. I will let you know what I find. I suspect that my new conclusion will be a risky change that will require much testing. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
An APC call can't execute managed code for reasons very similar to doing from a signal handler. On Fri, Dec 19, 2008 at 5:36 PM, Bill Holmes billholme...@gmail.com wrote: Kornél, After reading your mail a bunch more times and messing with the sample I think I finally get what you were saying. What I discovered was that the APC callback being a managed method gives mono a chance to check the thread state when crossing to and from the managed thread boundary. It is not the fact that you called an APC that was important. What is important is that the APC was a managed call. This does in fact give me some ideas on new things to try. I will let you know what I find. I suspect that my new conclusion will be a risky change that will require much testing. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono svn and ppc
On Fri, Dec 19, 2008 at 3:27 AM, Steven Munroe munro...@us.ibm.com wrote: found the bug. The update to mini-ppc.c (emit_memcpy) replaced ppc_lwzu macro with ppc_load_reg_update, but the definition of ppc_load_reg_update for PPC32 in ppc-codegen.h did not account for reorders parms (ppc_lwz (c, Rd, d, Ra) vs lwzu (c, Rd, Ra, d)). Thanks! I couldn't reproduce the bug on my own machine, but I've commited the bugfix. bye Mark ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Creating Managed COM objects from C++ (on linux).
Hi, I have implemented a COM object that allows creating of C# COM objects from C++ on Linux. (a bit like mscoree for .NET I think..) So I can do things like the following: TestComObject::IMyDotNetInterface *ptrMyDotNetInterface = NULL; if (S_OK != ::CoCreateInstance(TestComObject::CLSID_MyDotNetClass, NULL, CLSCTX_ALL, TestComObject::IID_IMyDotNetInterface, (void **)ptrMyDotNetInterface)) { fprintf(stderr, CoCreateInstance Failed\n); return 1; } ptrMyDotNetInterface-ShowCOMDialog(); For a COM object defined like the following: using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace TestComObject { [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid(03AD5D2D-2AFD-439f-8713-A4EC0705B4D9)] public interface IMyDotNetInterface { void ShowCOMDialog(); } [ClassInterface(ClassInterfaceType.None)] [Guid(0490E147-F2D2-4909-A4B8-3533D2F264D0)] public class MyDotNetClass : IMyDotNetInterface { public MyDotNetClass() {} public void ShowCOMDialog() { Console.WriteLine(Hello World); System.Windows.Forms.MessageBox.Show(Hello); } } } However in order to do this I had to convert from a MonoObject to a COM interface pointer. The only way I could work out how to do this was by using some internal mono functions. (removing static from mono src files ect.) comClassInstance = mono_object_new (m_domain, comClass); if (comClassInstance == NULL) { fprintf(stderr, Failed to create instance of %s.%s from assembly %s\n, classNamespace.c_str(), className.c_str(), assemblyName.c_str()); return 1; } // Get object callable from C++ mono_init_com_types(); // Internal mono function void *pCCW = (void*)ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal(comClassInstance); // Internal mono function cominterop_ccw_queryinterface(pCCW,(guint8*)riid, (void**)ppvObject); // Internal mono function I think I could replace ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal with mono_lookup_internal_calls but I don't know how to get around the need to call mono_init_com_types() and cominterop_ccw_queryinterface(). Any ideas anyone? Thanks Tom ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Creating Managed COM objects from C++ (on linux).
We have dealt with this by registering a global class factory method (that is implemented in C#) with native C++ code. I assume you are hosting the mono runtime? Take a look at the poor code example below and see if that gives you the idea. -bill /* C++ code */ void cppMain () { // Init Mono Runtme // Call managed InitManagedCOMFactory IUnknown* pObj; ManagedCOMFactoryCreateObject (CLSID_MyObj, pObj); IFoo* pFoo; pObj-QueryInterface (IID_IFoo, (void**)pFoo); } uint (*ManagedCOMFactoryCreateObject) (GUID*, IUnknown**); void RegsterManagedCOMFactoryCreateObject (void* ptr) { ManagedCOMFactoryCreateObject = ptr; } /* C# code */ void InitManagedCOMFactory () { RegsterManagedCOMFactoryCreateObject (ManagedCOMFactoryCreateObject); } uint ManagedCOMFactoryCreateObject (guid g, [MarshalAs (IUnknown)] out object retObj) { if (g == myGuid) retObj = new MyObject (); } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
Hi, If you need a quick fix you patch will do it. But it is just a workaround. What I suggested is that the bug is general, not related to Socket.Accept. You wrote in your original message: The problem is that the APC call does not cause the accept call to break. My test case shows that the APC is executed even if accept is not leaved. I don't know the exact solution because I don't know what the real bug is. I just wanted to show you that Mono behaves the same as MS.NET except that the thread is not terminated at exit so I believe this is the difference rather than any hack in Socket.Accept. The difference in thread state is a bug I believe that may cause other bugs if code checks for exact state value but I don't know if this is the case. The fact that I used a managed APC is not required I just have written the test case in C#. I believe that in this case the thread is aborted because the wrapper checks for abortion. Kornél Bill Holmes wrote: Kornél, After reading your mail a bunch more times and messing with the sample I think I finally get what you were saying. What I discovered was that the APC callback being a managed method gives mono a chance to check the thread state when crossing to and from the managed thread boundary. It is not the fact that you called an APC that was important. What is important is that the APC was a managed call. This does in fact give me some ideas on new things to try. I will let you know what I find. I suspect that my new conclusion will be a risky change that will require much testing. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
Hi, If aborting the thread is really that hard while it is stuck in accept, perhaps it would be easier to not abort it at all at shutdown, i.e. set a flag before calling accept (), and in the shutdown code, if the flag is set for a thread, simply ignore it. When the thread returns from accept (), it could check the thread/runtime state, and if it looks like the runtime is shutting down, simply exit. This has many races etc., but better than hanging at shutdown. Zoltan On Fri, Dec 19, 2008 at 6:11 PM, Bill Holmes billholme...@gmail.com wrote: Kornél, I do not understand what you example shows. I can understand the thread state problems. Is that all? Are you suggesting that I add to my patch to fix the state problem? Are you suggesting that the socket implementation is fine in svn and we need to address the abort/stop thread in a more general manner? Do you have any suggestions? What I do know is background threads that are blocked are causing mono to hang on exit. Foreground threads that are blocked should cause the process to hang on exit as that is how MS .Net behaves. Do you feel that we should not wait on background threads on exit, but simply kill them? I know it is a lot of questions but I am not certain of the direction you are trying to point me. This is a bug that I REALLY need fixed now. -bill ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] [PATCH] TcpChannel hang on Windows.
Hi, My conclusion is that there is no magic. The background thread is simply killed. finally is never printed altough it is in a constrained execution region. If you uncomment QueueUserAPC the wrapper will abort the thread and finally gets printed. But that is just a play with QueueUserAPC to study the runtime and Accept, not really necessary. Kornél Kornél Pál wrote: Hi, If you need a quick fix you patch will do it. But it is just a workaround. What I suggested is that the bug is general, not related to Socket.Accept. You wrote in your original message: The problem is that the APC call does not cause the accept call to break. My test case shows that the APC is executed even if accept is not leaved. I don't know the exact solution because I don't know what the real bug is. I just wanted to show you that Mono behaves the same as MS.NET except that the thread is not terminated at exit so I believe this is the difference rather than any hack in Socket.Accept. The difference in thread state is a bug I believe that may cause other bugs if code checks for exact state value but I don't know if this is the case. The fact that I used a managed APC is not required I just have written the test case in C#. I believe that in this case the thread is aborted because the wrapper checks for abortion. Kornél Bill Holmes wrote: Kornél, After reading your mail a bunch more times and messing with the sample I think I finally get what you were saying. What I discovered was that the APC callback being a managed method gives mono a chance to check the thread state when crossing to and from the managed thread boundary. It is not the fact that you called an APC that was important. What is important is that the APC was a managed call. This does in fact give me some ideas on new things to try. I will let you know what I find. I suspect that my new conclusion will be a risky change that will require much testing. -bill using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace BlockingAccept { class BlockingAccept { static Socket socket; static IntPtr threadHandle; delegate void APCProc(IntPtr dwParam); [DllImport(kernel32.dll)] static extern uint QueueUserAPC(APCProc pfnAPC, IntPtr hThread, IntPtr dwData); [DllImport(kernel32.dll)] static extern IntPtr GetCurrentThread(); [DllImport(kernel32.dll)] extern static IntPtr GetCurrentProcess(); [DllImport(kernel32.dll)] extern static bool DuplicateHandle(IntPtr sourceProcessHandle, IntPtr sourceHandle, IntPtr targetProcessHandle, out IntPtr targetHandle, uint desiredAccess, bool inheritHandle, uint dwOptions); [DllImport(kernel32.dll)] extern static bool CloseHandle(IntPtr handle); static void Main(string[] args) { Thread.BeginThreadAffinity(); Console.WriteLine(Main thread: + AppDomain.GetCurrentThreadId()); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Blocking = true; socket.Bind(new IPEndPoint(IPAddress.Loopback, 12345)); socket.Listen(1); Thread thread = new Thread(AcceptSocket); thread.IsBackground = true; thread.Start(); Thread.Sleep(1000); Console.WriteLine(before Abort); thread.Abort(); Console.WriteLine(after Abort); Thread.Sleep(1000); Console.WriteLine(New thread state: + thread.ThreadState.ToString()); //QueueUserAPC(APCCallback, threadHandle, IntPtr.Zero); CloseHandle(threadHandle); Thread.Sleep(1000); Console.WriteLine(New thread state: + thread.ThreadState.ToString()); Thread.EndThreadAffinity(); } static void APCCallback(IntPtr dwParam) { Console.WriteLine(APCCallback thread: + AppDomain.GetCurrentThreadId()); } static void AcceptSocket() { Thread.BeginThreadAffinity(); RuntimeHelpers.PrepareConstrainedRegions(); try { Console.WriteLine(New thread: + AppDomain.GetCurrentThreadId()); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), out threadHandle, 0, false, 2); Console.WriteLine(before Accept); Socket conn = socket.Accept(); Console.WriteLine(after Accept); conn.Close(); } finally { Console.WriteLine(finally); } Thread.EndThreadAffinity(); } } } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com
Re: [Mono-dev] Creating Managed COM objects from C++ (on linux).
On Fri, 2008-12-19 at 17:07 -0500, Bill Holmes wrote: We have dealt with this by registering a global class factory method (that is implemented in C#) with native C++ code. I assume you are hosting the mono runtime? Yes. Take a look at the poor code example below and see if that gives you the idea. Thanks for the idea! I think I would still prefer being able to do it via the mono c API and so not having an assembly coupled with my COM object, but a least I now have a solution if I can't do that. I guess I can use reflection, to search in the assembly for the class associated with the CLSID, in the implementation of ManagedCOMFactoryCreateObject to make it generic. Thanks, Tom -bill /* C++ code */ void cppMain () { // Init Mono Runtme // Call managed InitManagedCOMFactory IUnknown* pObj; ManagedCOMFactoryCreateObject (CLSID_MyObj, pObj); IFoo* pFoo; pObj-QueryInterface (IID_IFoo, (void**)pFoo); } uint (*ManagedCOMFactoryCreateObject) (GUID*, IUnknown**); void RegsterManagedCOMFactoryCreateObject (void* ptr) { ManagedCOMFactoryCreateObject = ptr; } /* C# code */ void InitManagedCOMFactory () { RegsterManagedCOMFactoryCreateObject (ManagedCOMFactoryCreateObject); } uint ManagedCOMFactoryCreateObject (guid g, [MarshalAs (IUnknown)] out object retObj) { if (g == myGuid) retObj = new MyObject (); } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] [PATCH] System.Messaging, support for BeginPeek/BeginReceive.
Hi, Attached is 2 patches that adds support for the async methods in System.Messaging (BeginReceive, BeginPeek, EndReceive and EndPeek). I have implemented all of the functionality for this in System.Messaging so the underlying messaging implementation does not need to. Please review. Mike. Index: System.Messaging/System.Messaging/ChangeLog === --- System.Messaging/System.Messaging/ChangeLog (revision 121890) +++ System.Messaging/System.Messaging/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2008-12-20 Michael Barker m...@middlesoft.co.uk + + * MessageQueue.cs: Added implementation for async methods: BeginReceive, + BeginPeek, EndReceive and EndPeek. + 2008-11-23 Michael Barker m...@middlesoft.co.uk * MessageQueue.cs: Added support for MessageQueueTransactionType methods, Index: System.Messaging/System.Messaging/MessageQueue.cs === --- System.Messaging/System.Messaging/MessageQueue.cs (revision 121890) +++ System.Messaging/System.Messaging/MessageQueue.cs (working copy) @@ -34,6 +34,7 @@ using System.ComponentModel; using System.Drawing; using System.Messaging.Design; +using System.Threading; using Mono.Messaging; @@ -372,47 +373,48 @@ #region Methods - [MonoTODO] public IAsyncResult BeginPeek () { - throw new NotImplementedException (); + return new PeekAsyncResult (null, this, InfiniteTimeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginPeek (TimeSpan timeout) { - throw new NotImplementedException (); + return new PeekAsyncResult (null, this, timeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginPeek (TimeSpan timeout, object stateObject) { - throw new NotImplementedException (); + return new PeekAsyncResult (stateObject, this, + timeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginPeek (TimeSpan timeout, object stateObject, AsyncCallback callback) { - throw new NotImplementedException (); - } - [MonoTODO] + return new PeekAsyncResult (stateObject, this, timeout, callback); + } + public IAsyncResult BeginReceive () { - throw new NotImplementedException (); + return new ReceiveAsyncResult (null, this, InfiniteTimeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginReceive (TimeSpan timeout) { - throw new NotImplementedException (); + return new ReceiveAsyncResult (null, this, + timeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginReceive (TimeSpan timeout, object stateObject) { - throw new NotImplementedException (); + return new ReceiveAsyncResult (stateObject, this, timeout, NullAsyncCallback); } - [MonoTODO] + public IAsyncResult BeginReceive (TimeSpan timeout, object stateObject, AsyncCallback callback) { - throw new NotImplementedException (); + return new ReceiveAsyncResult (stateObject, this, timeout, callback); } [MonoTODO] public static void ClearConnectionCache () @@ -445,15 +447,23 @@ QueueReference qRef = QueueReference.Parse (path); MessagingProviderLocator.GetProvider ().DeleteQueue (qRef); } - [MonoTODO] + public Message EndPeek (IAsyncResult asyncResult) { - throw new NotImplementedException (); + if (asyncResult == null) +throw new ArgumentNullException (); + + PeekAsyncResult result = (PeekAsyncResult) asyncResult; + return result.Message; } - [MonoTODO] + public Message EndReceive (IAsyncResult asyncResult) { - throw new NotImplementedException (); + if (asyncResult == null) +throw new ArgumentNullException (); + + ReceiveAsyncResult result = (ReceiveAsyncResult) asyncResult; + return result.Message; } public static bool Exists (string path) @@ -1154,5 +1164,96 @@ { return MessagingProviderLocator.GetProvider ().Exists (qRef); } + + internal void NullAsyncCallback (IAsyncResult result) + { + } + + internal class ReceiveAsyncResult : IAsyncResult { + + private readonly object asyncState; + protected readonly EventWaitHandle asyncWaitHandle; + protected volatile bool isCompleted; + protected readonly MessageQueue q; + private readonly Thread t; + protected Message message; + protected readonly TimeSpan timeout; + protected readonly AsyncCallback callback; + + public ReceiveAsyncResult (object asyncState, + MessageQueue q, + TimeSpan timeout, + AsyncCallback callback) + { +this.asyncState = asyncState; +this.asyncWaitHandle = new EventWaitHandle (false, EventResetMode.AutoReset); +this.q = q; +this.timeout = timeout; +this.callback = callback; +this.t = new Thread(run); +t.Start (); + } + + public object AsyncState { +