namespace System.Threading {
-#if NET_2_0
[Serializable]
- [ComVisibleAttribute (false)]
public sealed class CompressedStack : ISerializable {
-#else
- public class CompressedStack {
-#endif
private ArrayList _list;
internal CompressedStack (int length)
_list = (ArrayList) cs._list.Clone ();
}
- ~CompressedStack ()
- {
- }
-
-#if NET_2_0
[ComVisibleAttribute (false)]
public CompressedStack CreateCopy ()
{
- // FIXME: in 2.0 beta1 Object.ReferenceEquals (cs, cs.CreateCopy ()) == true !!!
- return this;
-// return new CompressedStack (this);
- }
-
- [MonoTODO ("incomplete")]
- public void GetObjectData (SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException ("info");
+ return new CompressedStack (this);
}
- static public CompressedStack Capture ()
+ public static CompressedStack Capture ()
{
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;
}
+ // NOTE: This method doesn't show in the class library status page because
+ // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
+ // But it's there!
[SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
[StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
static public CompressedStack GetCompressedStack ()
// Note: CompressedStack.GetCompressedStack doesn't return null
// like Thread.CurrentThread.GetCompressedStack if no compressed
// stack is present.
- return new CompressedStack (Thread.CurrentThread.GetCompressedStack ());
+ CompressedStack cs = Thread.CurrentThread.GetCompressedStack ();
+ if (cs == null) {
+ cs = CompressedStack.Capture ();
+ } else {
+ // merge the existing compressed stack (from a previous Thread) with the current
+ // Thread stack so we can assign "all of it" to yet another Thread
+ CompressedStack newstack = CompressedStack.Capture ();
+ for (int i=0; i < newstack._list.Count; i++)
+ cs._list.Add (newstack._list [i]);
+ }
+ return cs;
+ }
+
+ [MonoTODO ("incomplete")]
+ [ReflectionPermission (SecurityAction.Demand, MemberAccess = true)]
+ public void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException ("info");
}
- static public CompressedStackSwitcher SetCompressedStack (CompressedStack cs)
+ [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
+ static public void Run (CompressedStack compressedStack, ContextCallback callback, object state)
{
+ if (compressedStack == null)
+ throw new ArgumentException ("compressedStack");
+
Thread t = Thread.CurrentThread;
- CompressedStack ctcs = t.GetCompressedStack ();
- if (ctcs != null) {
- string msg = Locale.GetText ("You must Undo previous CompressedStack.");
- throw new SecurityException (msg);
+ CompressedStack original = null;
+ try {
+ original = t.GetCompressedStack ();
+ t.SetCompressedStack (compressedStack);
+ callback (state);
+ }
+ finally {
+ if (original != null)
+ t.SetCompressedStack (original);
}
- CompressedStackSwitcher csw = new CompressedStackSwitcher (ctcs, t);
- t.SetCompressedStack (cs);
- return csw;
}
-#endif
+
+ // internal stuff
internal bool Equals (CompressedStack cs)
{
if (IsEmpty ())