// 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;
Security
}
+#if NET_2_0
public struct AsyncFlowControl : IDisposable {
-
+#else
+ internal struct AsyncFlowControl : IDisposable {
+#endif
private Thread _t;
private AsyncFlowControlType _type;
}
}
}
-
-#endif
+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.
{
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;
}
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).
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)
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
}
}
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.
private IntPtr unused5;
private IntPtr unused6;
private IntPtr unused7;
- private IntPtr unused8;
#endregion
[ThreadStatic]
private IPrincipal _principal;
- private ExecutionContext _ec;
-
public static Context CurrentContext {
[SecurityPermission (SecurityAction.LinkDemand, Infrastructure=true)]
get {
}
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.");
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;
[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]