2009-09-26 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Sat, 26 Sep 2009 11:20:02 +0000 (11:20 -0000)
committerMark Probst <mark.probst@gmail.com>
Sat, 26 Sep 2009 11:20:02 +0000 (11:20 -0000)
* Thread.cs: Serialize the principal so as not to make it cross
appdomains.  Two new internal calls for copying byte arrays
between domains.

2009-09-26  Mark Probst  <mark.probst@gmail.com>

* Environment.cs: Corlib version bump.

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

mcs/class/corlib/System.Threading/ChangeLog
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/Environment.cs

index e47ef4877b282281525a3658c4d0948f52ea9a96..4f98cec59b90e63520a03ffc53f81f0cc068c82f 100644 (file)
@@ -1,3 +1,9 @@
+2009-09-26  Mark Probst  <mark.probst@gmail.com>
+
+       * Thread.cs: Serialize the principal so as not to make it cross
+       appdomains.  Two new internal calls for copying byte arrays
+       between domains.
+
 2009-09-25  Mark Probst  <mark.probst@gmail.com>
 
        * Thread.cs: The Thread class is split up into Thread and
index ae1f3692381afd9a9b2fc6c9982397e8fa871064..fbecc306113406eeea715a31a8fdcc46e104f39c 100644 (file)
@@ -120,7 +120,8 @@ namespace System.Threading {
                internal int managed_id;
 #endif
 
-               internal IPrincipal _principal;
+               internal byte[] _serialized_principal;
+               internal int _serialized_principal_version;
 
                /* If the current_lcid() isn't known by CultureInfo,
                 * it will throw an exception which may cause
@@ -157,6 +158,9 @@ namespace System.Threading {
                private ExecutionContext ec_to_set;
                #endregion
 
+               IPrincipal principal;
+               int principal_version;
+
                // the name of local_slots, current_thread and _ec is
                // important because they are used by the runtime.
                [ThreadStatic]
@@ -197,23 +201,60 @@ namespace System.Threading {
                        }
                }
 
+               /*
+                * These two methods return an array in the target
+                * domain with the same content as the argument.  If
+                * the argument is already in the target domain, then
+                * the argument is returned, otherwise a copy.
+                */
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern static byte[] ByteArrayToRootDomain (byte[] arr);
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private extern static byte[] ByteArrayToCurrentDomain (byte[] arr);
+
 #if !NET_2_1
                public static IPrincipal CurrentPrincipal {
                        get {
-                               IPrincipal p = null;
-                               InternalThread th = CurrentThread.Internal;
-                               lock (th) {
-                                       p = th._principal;
-                                       if (p == null) {
-                                               p = GetDomain ().DefaultPrincipal;
-                                               th._principal = p;
+                               Thread th = CurrentThread;
+
+                               if (th.principal_version != th.Internal._serialized_principal_version)
+                                       th.principal = null;
+
+                               if (th.principal != null)
+                                       return th.principal;
+
+                               if (th.Internal._serialized_principal != null) {
+                                       try {
+                                               BinaryFormatter bf = new BinaryFormatter ();
+                                               MemoryStream ms = new MemoryStream (ByteArrayToCurrentDomain (th.Internal._serialized_principal));
+                                               th.principal = (IPrincipal) bf.Deserialize (ms);
+                                               th.principal_version = th.Internal._serialized_principal_version;
+                                               return th.principal;
+                                       } catch (Exception) {
                                        }
                                }
-                               return p;
+
+                               th.principal = GetDomain ().DefaultPrincipal;
+                               th.principal_version = th.Internal._serialized_principal_version;
+                               return th.principal;
                        }
                        [SecurityPermission (SecurityAction.Demand, ControlPrincipal = true)]
                        set {
-                               CurrentThread.Internal._principal = value;
+                               Thread th = CurrentThread;
+
+                               ++th.Internal._serialized_principal_version;
+                               try {
+                                       BinaryFormatter bf = new BinaryFormatter ();
+                                       MemoryStream ms = new MemoryStream ();
+                                       bf.Serialize (ms, value);
+                                       th.Internal._serialized_principal = ByteArrayToRootDomain (ms.ToArray ());
+                               } catch (Exception) {
+                                       th.Internal._serialized_principal = null;
+                               }
+
+                               th.principal = value;
+                               th.principal_version = th.Internal._serialized_principal_version;
                        }
                }
 #endif
@@ -866,8 +907,7 @@ namespace System.Threading {
                        if (SecurityManager.SecurityEnabled)
                                ec_to_set = ExecutionContext.Capture ();
 #endif
-                       if (CurrentThread.Internal._principal != null)
-                               Internal._principal = CurrentThread.Internal._principal;
+                       Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
 
                        // Thread_internal creates and starts the new thread, 
 #if NET_2_1 && !MONOTOUCH
index 817751ea30ef501729ebc6f6d86ea96b801fc25b..820d13eaa8b75612eb1d8bb7d6437b2351537593 100644 (file)
@@ -1,3 +1,7 @@
+2009-09-26  Mark Probst  <mark.probst@gmail.com>
+
+       * Environment.cs: Corlib version bump.
+
 2009-09-24  Zoltan Varga  <vargaz@gmail.com>
 
        * Type.cs: Initialize the Missing field.
index 10557a2bdd02febe18ebad7744675d749f16d27b..a0a344382f597b4cb9b6aaf86f6543210d1262fa 100644 (file)
@@ -63,7 +63,7 @@ namespace System {
                 * Changes which are already detected at runtime, like the addition
                 * of icalls, do not require an increment.
                 */
-               private const int mono_corlib_version = 83;
+               private const int mono_corlib_version = 84;
 
 #if NET_2_0
                [ComVisible (true)]