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