2005-05-20 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Fri, 20 May 2005 14:11:04 +0000 (14:11 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Fri, 20 May 2005 14:11:04 +0000 (14:11 -0000)
* AsyncFlowControl.cs: Now available, as internal, in NET_1_1. This is
required to get some methods from SecurityContext and ExecutionContext
working.
* CompressedStack.cs: Now includes the current CompressedStack in a new
Capture.
* ExecutionContext.cs: Includes more methods in NET_1_1 to enable
ThreadPool.UnsafeQueueUserWorkItem to work properly (i.e. without
stack propagation).
* Thread.cs: Made ExecutionContext field accessible from the runtime.
Added stack propagation when Thread.Start is called.
* ThreadPool.cs: QueueUserWorkItem now does stack propagation (done in
the runtime), so I "fixed" UnsafeQueueUserWorkItem not to do so.

svn path=/trunk/mcs/; revision=44818

mcs/class/corlib/System.Threading/AsyncFlowControl.cs
mcs/class/corlib/System.Threading/ChangeLog
mcs/class/corlib/System.Threading/CompressedStack.cs
mcs/class/corlib/System.Threading/ExecutionContext.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System.Threading/ThreadPool.cs

index 82b37f3170d68c9814bfc43080757c43c7ff23af..37f355e73039010dabe23be592b8bc879dd99ccf 100644 (file)
@@ -26,8 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Security;
@@ -40,8 +38,11 @@ namespace System.Threading {
                Security
        }
 
+#if NET_2_0
        public struct AsyncFlowControl : IDisposable {
-
+#else
+       internal struct AsyncFlowControl : IDisposable {
+#endif
                private Thread _t;
                private AsyncFlowControlType _type;
 
@@ -78,5 +79,3 @@ namespace System.Threading {
                }
        }
 }
-
-#endif
index 8e475c246f5deb09e6ec63bdae5aa30140ed9357..6cbd1b82eb4997b0ec801ff54ebd45a10cb551e0 100644 (file)
@@ -1,3 +1,18 @@
+2005-05-20  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * AsyncFlowControl.cs: Now available, as internal, in NET_1_1. This is
+       required to get some methods from SecurityContext and ExecutionContext
+       working.
+       * CompressedStack.cs: Now includes the current CompressedStack in a new
+       Capture.
+       * ExecutionContext.cs: Includes more methods in NET_1_1 to enable 
+       ThreadPool.UnsafeQueueUserWorkItem to work properly (i.e. without
+       stack propagation).
+       * Thread.cs: Made ExecutionContext field accessible from the runtime.
+       Added stack propagation when Thread.Start is called.
+       * ThreadPool.cs: QueueUserWorkItem now does stack propagation (done in
+       the runtime), so I "fixed" UnsafeQueueUserWorkItem not to do so.
+
 2005-05-19  Miguel de Icaza  <miguel@novell.com>
 
        * Thread.cs: REmove warnings.
index 08343945b03c5860000a4de8140a78b8743d0e6d..464ef12bff84f1fa7dc31fee36668b40c92e917e 100644 (file)
@@ -77,6 +77,13 @@ namespace System.Threading {
                {
                        CompressedStack cs = new CompressedStack (0);
                        cs._list = SecurityFrame.GetStack (1);
+
+                       // include any current CompressedStack inside the new Capture
+                       CompressedStack currentCs = Thread.CurrentThread.GetCompressedStack ();
+                       if (currentCs != null) {
+                               for (int i=0; i < currentCs._list.Count; i++)
+                                       cs._list.Add (currentCs._list [i]);
+                       }
                        return cs;
                }
 
index 08b217a046e5a309da6297a56ea5782ed6175ba4..d3176bfd37412df468819ac8f72e87339a50c3bf 100644 (file)
@@ -106,7 +106,6 @@ namespace System.Threading {
                        set { _suppressFlow = value; }
                }
 
-#if NET_2_0
                // Note: Previous to version 2.0 only the CompressedStack and (sometimes!) the WindowsIdentity
                // were propagated to new threads. This is why ExecutionContext is internal in before NET_2_0.
                // It also means that all newer context classes should be here (i.e. inside the #if NET_2_0).
@@ -124,7 +123,7 @@ namespace System.Threading {
 
                        ec.FlowSuppressed = false;
                }
-               
+#if NET_2_0
                [MonoTODO ("only the SecurityContext is considered")]
                [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
                public static void Run (ExecutionContext executionContext, ContextCallback callBack, object state)
@@ -139,13 +138,12 @@ namespace System.Threading {
 
                        SecurityContext.Run (executionContext.SecurityContext, callBack, state);
                }
-               
+#endif
                public static AsyncFlowControl SuppressFlow ()
                {
                        Thread t = Thread.CurrentThread;
                        t.ExecutionContext.FlowSuppressed = true;
                        return new AsyncFlowControl (t, AsyncFlowControlType.Execution);
                }
-#endif
        }
 }
index 96d0af343913e10c1de6cf87fbf1bdb56e839913..a0af3b2a00e4dd3e85ae1c1aaf1216b2bc46aa10 100644 (file)
@@ -86,6 +86,7 @@ namespace System.Threading
                private int serialized_culture_info_len;
                private IntPtr serialized_ui_culture_info;
                private int serialized_ui_culture_info_len;
+               private ExecutionContext _ec;
                /* 
                 * These fields are used to avoid having to increment corlib versions
                 * when a new field is added to the unmanaged MonoThread structure.
@@ -97,7 +98,6 @@ namespace System.Threading
                private IntPtr unused5;
                private IntPtr unused6;
                private IntPtr unused7;
-               private IntPtr unused8;
                #endregion
 
                [ThreadStatic] 
@@ -109,8 +109,6 @@ namespace System.Threading
                
                private IPrincipal _principal;
 
-               private ExecutionContext _ec;
-               
                public static Context CurrentContext {
                        [SecurityPermission (SecurityAction.LinkDemand, Infrastructure=true)]
                        get {
@@ -628,6 +626,17 @@ namespace System.Threading
                }
 
                public void Start() {
+                       // propagate informations from the original thread to the new thread
+#if NET_2_0
+                       if (!ExecutionContext.IsFlowSuppressed ())
+                               _ec = ExecutionContext.Capture ();
+#else
+                       // before 2.0 this was only used for security (mostly CAS) so we
+                       // do this only if the security manager is active
+                       if (SecurityManager.SecurityEnabled)
+                               _ec = ExecutionContext.Capture ();
+#endif
+
                        // Thread_internal creates and starts the new thread, 
                        if (Thread_internal(threadstart) == (IntPtr) 0)
                                throw new SystemException ("Thread creation failed.");
index c0c8ad58738323040f2b7addaead479782cf6bc6..69ee9531fd12bf60b3fbb5286022e3cf7560b9ae 100644 (file)
 using System.Collections;
 using System.Globalization;
 using System.Runtime.CompilerServices;
+using System.Runtime.Remoting.Messaging;
 using System.Security.Permissions;
 
 namespace System.Threading {
 
+#if NET_2_0
+       public static class ThreadPool {
+#else
        public sealed class ThreadPool {
 
                private ThreadPool ()
                {
                        /* nothing to do */
                }
-
+#endif
                public static bool BindHandle (IntPtr osHandle)
                {
                        return true;
@@ -132,10 +136,19 @@ namespace System.Threading {
                [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
                public static bool UnsafeQueueUserWorkItem (WaitCallback callback, object state)
                {
-                       IAsyncResult ar = callback.BeginInvoke (state, null, null);
-                       if (ar == null)
-                               return false;
-                       return true;
+                       // no stack propagation here (that's why it's unsafe and requires extra security permissions)
+                       IAsyncResult ar = null;
+                       try {
+                               if (!ExecutionContext.IsFlowSuppressed ())
+                                       ExecutionContext.SuppressFlow (); // on current thread only
+
+                               ar = callback.BeginInvoke (state, null, null);
+                       }
+                       finally {
+                               if (ExecutionContext.IsFlowSuppressed ())
+                                       ExecutionContext.RestoreFlow ();
+                       }
+                       return (ar != null);
                }
                
                [MonoTODO]