Author: miguel
Date: 2007-01-25 01:16:04 -0500 (Thu, 25 Jan 2007)
New Revision: 71651

Added:
   trunk/olive/class/WindowsBase/Test/System.Windows.Threading/
   trunk/olive/class/WindowsBase/Test/System.Windows.Threading/DispatcherTest.cs
Modified:
   trunk/olive/class/WindowsBase/
   trunk/olive/class/WindowsBase/Assembly/AssemblyInfo.cs
   trunk/olive/class/WindowsBase/ChangeLog
   trunk/olive/class/WindowsBase/System.Windows.Threading/ChangeLog
   trunk/olive/class/WindowsBase/System.Windows.Threading/Dispatcher.cs
   trunk/olive/class/WindowsBase/WindowsBase_test.dll.sources
Log:
2007-01-25  Miguel de Icaza  <[EMAIL PROTECTED]>

        * Assembly/AssemblyInfo.cs: Use the right key to sign things so we
        can test on Windows the resulting nunit tests.

2007-01-25  Miguel de Icaza  <[EMAIL PROTECTED]>

        * Dispatcher.cs: Check frame.Continue for early termination.

        PokableQueue: new class used so we can move DispatcherOperation
        tasks from one thread to another. 

2007-01-24  Miguel de Icaza  <[EMAIL PROTECTED]>

        * Dispatcher.cs: Implement reprioritization.

        We now take locks instead of using a separate async queue, as
        things like DispatcherOperation.Priority (reprioritization) can be
        called from a separate thread without crashing.

Added tests




Property changes on: trunk/olive/class/WindowsBase
___________________________________________________________________
Name: svn:ignore
   + TestResult*log
TestResult*xml


Modified: trunk/olive/class/WindowsBase/Assembly/AssemblyInfo.cs
===================================================================
--- trunk/olive/class/WindowsBase/Assembly/AssemblyInfo.cs      2007-01-25 
06:12:54 UTC (rev 71650)
+++ trunk/olive/class/WindowsBase/Assembly/AssemblyInfo.cs      2007-01-25 
06:16:04 UTC (rev 71651)
@@ -29,5 +29,5 @@
 */
 
 [assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../mono.pub")]
+[assembly: AssemblyKeyFile ("../msfinal3.pub")]
 

Modified: trunk/olive/class/WindowsBase/ChangeLog
===================================================================
--- trunk/olive/class/WindowsBase/ChangeLog     2007-01-25 06:12:54 UTC (rev 
71650)
+++ trunk/olive/class/WindowsBase/ChangeLog     2007-01-25 06:16:04 UTC (rev 
71651)
@@ -1,3 +1,8 @@
+2007-01-25  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * Assembly/AssemblyInfo.cs: Use the right key to sign things so we
+       can test on Windows the resulting nunit tests.
+
 2005-07-24  Iain McCoy  <[EMAIL PROTECTED]>
 
        * Test/AttachedProperties.cs: made LocalValueEnumerator test not

Modified: trunk/olive/class/WindowsBase/System.Windows.Threading/ChangeLog
===================================================================
--- trunk/olive/class/WindowsBase/System.Windows.Threading/ChangeLog    
2007-01-25 06:12:54 UTC (rev 71650)
+++ trunk/olive/class/WindowsBase/System.Windows.Threading/ChangeLog    
2007-01-25 06:16:04 UTC (rev 71651)
@@ -1,3 +1,18 @@
+2007-01-25  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * Dispatcher.cs: Check frame.Continue for early termination.
+
+       PokableQueue: new class used so we can move DispatcherOperation
+       tasks from one thread to another. 
+
+2007-01-24  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * Dispatcher.cs: Implement reprioritization.
+
+       We now take locks instead of using a separate async queue, as
+       things like DispatcherOperation.Priority (reprioritization) can be
+       called from a separate thread without crashing.
+
 2007-01-23  Miguel de Icaza  <[EMAIL PROTECTED]>
 
        * Dispatcher.cs: Start with the Async methods.

Modified: trunk/olive/class/WindowsBase/System.Windows.Threading/Dispatcher.cs
===================================================================
--- trunk/olive/class/WindowsBase/System.Windows.Threading/Dispatcher.cs        
2007-01-25 06:12:54 UTC (rev 71650)
+++ trunk/olive/class/WindowsBase/System.Windows.Threading/Dispatcher.cs        
2007-01-25 06:16:04 UTC (rev 71651)
@@ -70,21 +70,18 @@
 
                const int TOP_PRIO = (int)DispatcherPriority.Send;
                Thread base_thread;
-               Queue [] priority_queues = new Queue [TOP_PRIO+1];
+               PokableQueue [] priority_queues = new PokableQueue [TOP_PRIO+1];
 
                Flags flags;
                int queue_bits;
                EventWaitHandle wait;
-               Queue async_tasks;
-               bool want_async_lookup;
                
                Dispatcher (Thread t)
                {
                        base_thread = t;
                        for (int i = 1; i <= (int) DispatcherPriority.Send; i++)
-                               priority_queues [i] = new Queue ();
+                               priority_queues [i] = new PokableQueue ();
                        wait = new EventWaitHandle (false, 
EventResetMode.AutoReset);
-                       async_tasks = new Queue ();
                }
 
                public bool CheckAccess ()
@@ -195,32 +192,28 @@
 
                void Queue (DispatcherPriority priority, object x)
                {
-                       if (CheckAccess ()){
-                               int p = ((int) priority);
-                               Queue q = priority_queues [p];
+                       int p = ((int) priority);
+                       PokableQueue q = priority_queues [p];
+                       
+                       lock (q){
                                int flag = 1 << p;
                                q.Enqueue (x);
                                queue_bits |= flag;
-                       } else {
-                               lock (async_tasks){
-                                       want_async_lookup = true;
-                                       async_tasks.Enqueue (x);
-                               }
+                       }
+                       if (Thread.CurrentThread != base_thread)
                                wait.Reset ();
-                       }
                }
 
                internal void Reprioritize (DispatcherOperation op, 
DispatcherPriority oldpriority)
                {
-                       if (CheckAccess ()){
-                               int np = (int) op.Priority;
-                               int oldp = (int) oldpriority;
-                               Queue q = priority_queues [oldp];
+                       int np = (int) op.Priority;
+                       int oldp = (int) oldpriority;
+                       PokableQueue q = priority_queues [oldp];
 
-                               // TODO: replace queue, with a queue that we 
can manipulate
-                               
-                       } else {
+                       lock (q){
+                               q.Remove (op);
                        }
+                       Queue (op.Priority, op);
                }
                
                public static Dispatcher CurrentDispatcher {
@@ -295,7 +288,6 @@
 
                        priority_queues = null;
                        wait = null;
-                       async_tasks = null;
                }
                
                void RunFrame (DispatcherFrame frame)
@@ -306,21 +298,31 @@
                                        for (int i = TOP_PRIO; i > 0 && 
queue_bits != 0; i--){
                                                int current_bit = queue_bits & 
(1 << i);
                                                if (current_bit != 0){
-                                                       Queue q = 
priority_queues [i];
+                                                       PokableQueue q = 
priority_queues [i];
 
                                                        do {
-                                                               
DispatcherOperation task = (DispatcherOperation) q.Dequeue ();
+                                                               
DispatcherOperation task;
+                                                               
+                                                               lock (q){
+                                                                       task = 
(DispatcherOperation) q.Dequeue ();
+                                                               }
+                                                               
                                                                task.Invoke ();
 
+                                                               if 
(!frame.Continue)
+                                                                       return;
+                                                               
                                                                if 
(HasShutdownStarted){
                                                                        
PerformShutdown ();
                                                                        return;
                                                                }
                                                                
                                                                // if we are 
done with this queue, leave.
-                                                               if (q.Count == 
0){
-                                                                       
queue_bits &= ~(1 << i);
-                                                                       break;
+                                                               lock (q){
+                                                                       if 
(q.Count == 0){
+                                                                               
queue_bits &= ~(1 << i);
+                                                                               
break;
+                                                                       }
                                                                }
 
                                                                //
@@ -333,15 +335,6 @@
                                        }
                                }
                                wait.WaitOne ();
-                               if (want_async_lookup){
-                                       lock (async_tasks){
-                                               DispatcherOperation op;
-
-                                               while ((op = 
(DispatcherOperation) async_tasks.Dequeue ()) != null)
-                                                       Queue (op.Priority, op);
-                                               want_async_lookup = false;
-                                       }
-                               }
                        } while (frame.Continue);
                }
                
@@ -369,4 +362,69 @@
                public event EventHandler ShutdownStarted;
                public event EventHandler ShutdownFinished;
        }
+
+       internal class PokableQueue {
+               const int initial_capacity = 32;
+
+               int size, head, tail;
+               object [] array;
+
+               internal PokableQueue (int capacity) 
+               {
+                       array = new object [capacity];
+               }
+
+               internal PokableQueue () : this (initial_capacity)
+               {
+               }
+
+               public void Enqueue (object obj)
+               {
+                        if (size == array.Length)
+                                Grow ();
+                        array[tail] = obj;
+                        tail = (tail+1) % array.Length;
+                        size++;
+               }
+
+               public object Dequeue ()
+                {
+                        if (size < 1)
+                                throw new InvalidOperationException ();
+                        object result = array[head];
+                        array [head] = null;
+                        head = (head + 1) % array.Length;
+                        size--;
+                        return result;
+                }
+
+               void Grow () {
+                        int newc = array.Length * 2;
+                        object[] new_contents = new object[newc];
+                        array.CopyTo (new_contents, 0);
+                        array = new_contents;
+                        head = 0;
+                        tail = head + size;
+                }
+
+               public int Count {
+                       get {
+                               return size;
+                       }
+               }
+
+               public void Remove (object obj)
+               {
+                       for (int i = 0; i < size; i++){
+                               if (array [(head+i) % array.Length] == obj){
+                                       for (int j = i; j < size-i; j++)
+                                               array [(head +j) % 
array.Length] = array [(head+j+1) % array.Length];
+                                       size--;
+                                       if (size < 0)
+                                               size = array.Length-1;
+                                       tail--;
+                               }
+                       }
+               }
+       }
 }

Added: 
trunk/olive/class/WindowsBase/Test/System.Windows.Threading/DispatcherTest.cs
===================================================================
--- 
trunk/olive/class/WindowsBase/Test/System.Windows.Threading/DispatcherTest.cs   
    2007-01-25 06:12:54 UTC (rev 71650)
+++ 
trunk/olive/class/WindowsBase/Test/System.Windows.Threading/DispatcherTest.cs   
    2007-01-25 06:16:04 UTC (rev 71651)
@@ -0,0 +1,140 @@
+//
+// Tests for System.Windows.Threading.Dispatcher.cs
+//
+// Author:
+//    Miguel de Icaza ([EMAIL PROTECTED])
+//
+
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// 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 NUnit.Framework;
+using System;
+using System.IO;
+using System.Globalization;
+using System.Windows.Threading;
+using System.Threading;
+
+namespace MonoTests.System.Web.UI.WebControls
+{
+
+       delegate void Action ();
+       
+       [TestFixture]
+       public class DispatcherTest {
+               EventWaitHandle wait, wait2;
+               DispatcherOperation op;
+               
+               [SetUp]
+               public void DispatcherSetup ()
+               {
+                       wait = new EventWaitHandle (false, 
EventResetMode.AutoReset);
+                       wait2 = new EventWaitHandle (false, 
EventResetMode.AutoReset);
+               }
+
+               //
+               // Tests that fields in a DispatcherOperation can be issued from
+               // a separate thread
+               //
+               [Test]
+               public void TestDispatcherOpOnThread ()
+               {
+                       Thread t = new Thread (new ThreadStart (thread));
+                       Dispatcher d = Dispatcher.CurrentDispatcher;
+                       
+                       t.Start ();
+                       op = Dispatcher.CurrentDispatcher.BeginInvoke 
(DispatcherPriority.Normal, (Action) delegate {
+                               Console.WriteLine ("Some methods");
+                       });
+                       wait.Set ();
+                       wait2.WaitOne ();
+               }
+
+               void thread ()
+               {
+                       wait.WaitOne ();
+                       op.Priority = DispatcherPriority.DataBind;
+                       wait2.Set ();
+               }
+
+               [Test]
+               public void TestDispatcherOrder ()
+               {
+                       Dispatcher d = Dispatcher.CurrentDispatcher;
+
+                       DispatcherFrame frame = new DispatcherFrame ();
+                       bool fail = true;
+                       int next = 1;
+                       
+                       d.BeginInvoke (DispatcherPriority.Normal, (Action) 
delegate {
+                               if (next != 3)
+                                       throw new Exception ("Expected state 3, 
got " + next.ToString ());
+
+                               next = 4;
+                               Console.WriteLine ("First");
+                       });
+                       d.BeginInvoke (DispatcherPriority.Normal, (Action) 
delegate {
+                               if (next != 4)
+                                       throw new Exception ("Expected state 4, 
got " + next.ToString ());
+
+                               next = 5;
+                               Console.WriteLine ("Second");
+                       });
+                       d.BeginInvoke (DispatcherPriority.Send, (Action) 
delegate {
+                               if (next != 1)
+                                       throw new Exception ("Expected state 1, 
got " + next.ToString ());
+                               next = 2;
+                               Console.WriteLine ("High Priority");
+                               d.BeginInvoke (DispatcherPriority.Send, 
(Action) delegate {
+                                       if (next != 2)
+                                               throw new Exception ("Expected 
state 2, got " + next.ToString ());
+
+                                       next = 3;
+                                       Console.WriteLine ("INSERTED");
+                               });
+                       });
+                       d.BeginInvoke (DispatcherPriority.SystemIdle, (Action) 
delegate {
+                               if (next != 6)
+                                       throw new Exception ("Expected state 6, 
got " + next.ToString ());
+                               
+                               Console.WriteLine ("Idle");
+                               frame.Continue = false;
+                               fail = false;
+                       });
+                       
+                       d.BeginInvoke (DispatcherPriority.Normal, (Action) 
delegate {
+                               if (next != 5)
+                                       throw new Exception ("Expected state 5, 
got " + next.ToString ());
+                               next = 6;
+                               Console.WriteLine ("Last normal");
+                       });
+                       
+                       Dispatcher.PushFrame (frame);
+
+                       if (fail)
+                               throw new Exception ("Expected all states to 
run");
+               }
+       }
+}
+
+


Property changes on: 
trunk/olive/class/WindowsBase/Test/System.Windows.Threading/DispatcherTest.cs
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/olive/class/WindowsBase/WindowsBase_test.dll.sources
===================================================================
--- trunk/olive/class/WindowsBase/WindowsBase_test.dll.sources  2007-01-25 
06:12:54 UTC (rev 71650)
+++ trunk/olive/class/WindowsBase/WindowsBase_test.dll.sources  2007-01-25 
06:16:04 UTC (rev 71651)
@@ -1 +1,2 @@
 AttachedProperties.cs
+System.Windows.Threading/DispatcherTest.cs

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to