dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] pnetlib ./ChangeLog System.Windows.Forms/Contro...


From: Heiko Weiss
Subject: [dotgnu-pnet-commits] pnetlib ./ChangeLog System.Windows.Forms/Contro...
Date: Tue, 11 Apr 2006 15:34:08 +0000

CVSROOT:        /sources/dotgnu-pnet
Module name:    pnetlib
Branch:         
Changes by:     Heiko Weiss <address@hidden>    06/04/11 15:34:08

Modified files:
        .              : ChangeLog 
        System.Windows.Forms: Control.cs 

Log message:
        fixed deadlock with Control.Invoke.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnetlib/ChangeLog.diff?tr1=1.2379&tr2=1.2380&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnetlib/System.Windows.Forms/Control.cs.diff?tr1=1.119&tr2=1.120&r1=text&r2=text

Patches:
Index: pnetlib/ChangeLog
diff -u pnetlib/ChangeLog:1.2379 pnetlib/ChangeLog:1.2380
--- pnetlib/ChangeLog:1.2379    Thu Apr  6 10:06:16 2006
+++ pnetlib/ChangeLog   Tue Apr 11 15:34:08 2006
@@ -1,3 +1,7 @@
+2006-04-11  Heiko Weiss  <address@hidden>
+
+       * System.Windows.Forms/Control.cs: Fixed deadlock with invokes.
+
 2006-04-06  Heiko Weiss  <address@hidden>
 
        * System.Windows.Forms/Control.cs,
Index: pnetlib/System.Windows.Forms/Control.cs
diff -u pnetlib/System.Windows.Forms/Control.cs:1.119 
pnetlib/System.Windows.Forms/Control.cs:1.120
--- pnetlib/System.Windows.Forms/Control.cs:1.119       Thu Apr  6 10:06:16 2006
+++ pnetlib/System.Windows.Forms/Control.cs     Tue Apr 11 15:34:08 2006
@@ -141,6 +141,12 @@
                        bComplete = false;                      // This event 
hasn't completed
                        waitHandle = new ManualResetEvent(false);
                }
+               
+               ~InvokeAsyncResult() {
+                       if( null != waitHandle ) {
+                               waitHandle.Close();
+                       }
+               }
 
                public void WaitToComplete()
                {
@@ -321,51 +327,58 @@
 
 #if CONFIG_COMPONENT_MODEL
 
+       private Queue invokeEventQueue = new Queue();
+
        // Implement the ISynchronizeInvoke interface.
        private void ProcessInvokeEvent(IntPtr i_gch)   
        {
-               GCHandle gch = (GCHandle)i_gch;
-               InvokeParameters iParm = (InvokeParameters)gch.Target;
-
-               Delegate dg = iParm.method;
-               Object ro = dg.DynamicInvoke(iParm.args);
-
-               InvokeAsyncResult ar = iParm.wr;
+               lock( this.invokeEventQueue ) {
+                       
+                       while( this.invokeEventQueue.Count > 0 ) {
+                               InvokeParameters iParm = (InvokeParameters) 
invokeEventQueue.Dequeue();
+       
+                               Delegate dg = iParm.method;
+                               Object ro = dg.DynamicInvoke(iParm.args);
                
-               if( ar != null )
-               {
-                       ar.retObject = ro;
-                       ar.SetComplete();
+                               InvokeAsyncResult ar = iParm.wr;
+                               
+                               if( ar != null )
+                               {
+                                       ar.retObject = ro;
+                                       ar.SetComplete();
+                               }
+                       }
                }
-               gch.Free();
        }
 
        [TODO]
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public IAsyncResult BeginInvoke(Delegate method, Object[] args)
                        {
-                               InvokeParameters iParm = new InvokeParameters();
-                               InvokeAsyncResult ar = new InvokeAsyncResult();
-                               if( args != null )
-                               {
-                                       ar.AsyncState = args[args.Length - 1];
-                               }
-                               GCHandle gch = GCHandle.Alloc(iParm);
-                               IntPtr i_gch = (IntPtr)gch;
-
-                               iParm.method = method;
-                               iParm.args   = args;
-                               iParm.wr = ar;
+                               lock( this.invokeEventQueue ) {
 
-                               if(toolkitWindow == null)
-                               {
-                                       CreateControlInner();
+                                       InvokeParameters iParm = new 
InvokeParameters();
+                                       InvokeAsyncResult ar = new 
InvokeAsyncResult();
+                                       if( args != null )
+                                       {
+                                               ar.AsyncState = 
args[args.Length - 1];
+                                       }
+                                       
+                                       iParm.method = method;
+                                       iParm.args   = args;
+                                       iParm.wr = ar;
+       
+                                       if(toolkitWindow == null)
+                                       {
+                                               CreateControlInner();
+                                       }
+                                       
+                                       this.invokeEventQueue.Enqueue( iParm );
+       
+                                       
toolkitWindow.SendBeginInvoke(IntPtr.Zero);
+       
+                                       return ar;
                                }
-
-                               lock(this)      // this may not be necessary
-                                       toolkitWindow.SendBeginInvoke(i_gch);
-
-                               return ar;
                        }
 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -379,14 +392,27 @@
        public Object EndInvoke(IAsyncResult result)
                        {
                                InvokeAsyncResult ar = (result as 
InvokeAsyncResult);
-                               ar.WaitToComplete();
+                               if( !ar.IsCompleted ) { // it could be that we 
processed it already, so it might be completed
+                                       if( !InvokeRequired ) {
+                                               // we do not need to wait for 
the callback from toolkit.
+                                               // all waiting invokes will be 
processed.
+                                               this.ProcessInvokeEvent( 
IntPtr.Zero ); 
+                                       }
+                                       else {
+                                               ar.WaitToComplete();
+                                       }
+                               }
                                return ar.retObject;
                        }
 
        public Object Invoke(Delegate method, Object[] args)
                        {
-                               IAsyncResult ar = this.BeginInvoke(method,args);
-                               return this.EndInvoke(ar);
+                               if( !InvokeRequired ) {         // no need to 
use toolkit, do the invoke directly
+                                       return method.DynamicInvoke( args );
+                               }
+                               InvokeAsyncResult ar = 
this.BeginInvoke(method,args) as InvokeAsyncResult;
+                               ar.WaitToComplete();
+                               return ar.retObject;
                        }
 #if CONFIG_COMPONENT_MODEL
        [EditorBrowsable(EditorBrowsableState.Advanced)]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]