New tests.
[mono.git] / mcs / class / corlib / System.Threading / ExecutionContext.cs
index 465805a856786cd0b4e8e88f0b7f7825fef1bf44..684caf0a2e4fc928c72e11a6fe4ae096e2563c71 100644 (file)
@@ -1,12 +1,11 @@
 // 
 // System.Threading.ExecutionContext.cs
 //
-// Author:
-//   Lluis Sanchez (lluis@novell.com)
+// Authors:
+//     Lluis Sanchez (lluis@novell.com)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// Copyright (C) Novell, Inc., 2004
-//
-
+// Copyright (C) 2004-2005 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
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
+using System.Security;
+using System.Security.Permissions;
+
+namespace System.Threading {
 
-namespace System.Threading 
-{
-       [ComVisible (false)]
        [Serializable]
-       public sealed class ExecutionContext : ISerializable
-       {
+       public sealed class ExecutionContext : ISerializable {
+#if !MOONLIGHT
+               private SecurityContext _sc;
+#endif
+               private bool _suppressFlow;
+               private bool _capture;
+
                internal ExecutionContext ()
                {
                }
+
+               internal ExecutionContext (ExecutionContext ec)
+               {
+#if !MOONLIGHT
+                       if (ec._sc != null)
+                               _sc = new SecurityContext (ec._sc);
+#endif
+                       _suppressFlow = ec._suppressFlow;
+                       _capture = true;
+               }
                
                [MonoTODO]
                internal ExecutionContext (SerializationInfo info, StreamingContext context)
@@ -49,55 +62,93 @@ namespace System.Threading
                        throw new NotImplementedException ();
                }
                
-               [MonoTODO]
-               public static ExecutionContext Capture()
+               public static ExecutionContext Capture ()
                {
-                       throw new NotImplementedException ();
+                       ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
+                       if (ec.FlowSuppressed)
+                               return null;
+
+                       ExecutionContext capture = new ExecutionContext (ec);
+#if !MOONLIGHT
+                       if (SecurityManager.SecurityEnabled)
+                               capture.SecurityContext = SecurityContext.Capture ();
+#endif
+                       return capture;
                }
                
-               [MonoTODO]
-               public ExecutionContext CreateCopy()
+               public ExecutionContext CreateCopy ()
                {
-                       throw new NotImplementedException ();
+                       if (!_capture)
+                               throw new InvalidOperationException ();
+
+                       return new ExecutionContext (this);
                }
 
                [MonoTODO]
+               [ReflectionPermission (SecurityAction.Demand, MemberAccess = true)]
                public void GetObjectData (SerializationInfo info, StreamingContext context)
                {
+                       if (info == null)
+                               throw new ArgumentNullException ("info");
                        throw new NotImplementedException ();
                }
                
-               [MonoTODO]
-               public static bool IsFlowSuppressed()
-               {
-                       throw new NotImplementedException ();
+               // internal stuff
+#if !MOONLIGHT
+               internal SecurityContext SecurityContext {
+                       get {
+                               if (_sc == null)
+                                       _sc = new SecurityContext ();
+                               return _sc;
+                       }
+                       set { _sc = value; }
+               }
+#endif
+               internal bool FlowSuppressed {
+                       get { return _suppressFlow; }
+                       set { _suppressFlow = value; }
                }
 
-               [MonoTODO]
-               public static void RestoreFlow()
+               // 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).
+
+               public static bool IsFlowSuppressed ()
                {
-                       throw new NotImplementedException ();
+                       return Thread.CurrentThread.ExecutionContext.FlowSuppressed;
                }
-               
-               [MonoTODO]
-               public static void Run (ExecutionContext executionContext, ContextCallback callBack, object state)
+
+               public static void RestoreFlow ()
                {
-                       throw new NotImplementedException ();
+                       ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
+                       if (!ec.FlowSuppressed)
+                               throw new InvalidOperationException ();
+
+                       ec.FlowSuppressed = false;
                }
-               
-               [MonoTODO]
-               public static ExecutionContextSwitcher SetExecutionContext (ExecutionContext executionContext)
+
+#if !MOONLIGHT
+               [MonoTODO ("only the SecurityContext is considered")]
+               [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
+               public static void Run (ExecutionContext executionContext, ContextCallback callback, object state)
                {
-                       throw new NotImplementedException ();
+                       if (executionContext == null) {
+                               throw new InvalidOperationException (Locale.GetText (
+                                       "Null ExecutionContext"));
+                       }
+
+                       // FIXME: supporting more than one context (the SecurityContext)
+                       // will requires a rewrite of this method
+
+                       SecurityContext.Run (executionContext.SecurityContext, callback, state);
                }
 
-               [MonoTODO]
-               public static AsyncFlowControl SuppressFlow()
+               public static AsyncFlowControl SuppressFlow ()
                {
-                       throw new NotImplementedException ();
+                       Thread t = Thread.CurrentThread;
+                       t.ExecutionContext.FlowSuppressed = true;
+                       return new AsyncFlowControl (t, AsyncFlowControlType.Execution);
                }
-
+#endif
        }
 }
-
-#endif