[bcl] Remove NET_4_0 defines from class libs.
[mono.git] / mcs / class / corlib / System.Threading / CompressedStack.cs
index 707f00de3b68e293a420ba8d330369fe2025d1ca..e440ba068b70b52d7a9cc3dcca3d9ea42cf4c733 100644 (file)
@@ -1,14 +1,11 @@
 //
 // System.Threading.Thread.cs
 //
-// Author:
-//   Zoltan Varga (vargaz@freemail.hu)
+// Authors:
+//     Zoltan Varga (vargaz@freemail.hu)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// (C) 2004 Novell (http://www.novell.com)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// 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.
 //
 
-namespace System.Threading
-{
-       public class CompressedStack {
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Security.Permissions;
+
+namespace System.Threading {
+
+       [Serializable]
+       public sealed class CompressedStack : ISerializable {
+               private ArrayList _list;
+
+               internal CompressedStack (int length)
+               {
+                       if (length > 0)
+                               _list = new ArrayList (length);
+               }
+
+               internal CompressedStack (CompressedStack cs)
+               {
+                       if ((cs != null) && (cs._list != null))
+                               _list = (ArrayList) cs._list.Clone ();
+               }
+
+               [ComVisibleAttribute (false)]
+               public CompressedStack CreateCopy ()
+               {
+                       return new CompressedStack (this);
+               }
 
-               internal CompressedStack ()
+               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;
                }
 
-               ~CompressedStack ()
+               // 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!
+               [SecurityCritical]
+               static public CompressedStack GetCompressedStack ()
                {
+                       // Note: CompressedStack.GetCompressedStack doesn't return null
+                       // like Thread.CurrentThread.GetCompressedStack if no compressed
+                       // stack is present.
+                       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")]
+               [SecurityCritical]
+               public void GetObjectData (SerializationInfo info, StreamingContext context)
+               {
+                       if (info == null)
+                               throw new ArgumentNullException ("info");
+               }
+
+               [SecurityCritical]
+               static public void Run (CompressedStack compressedStack, ContextCallback callback, object state)
+               {
+                       if (compressedStack == null)
+                               throw new ArgumentException ("compressedStack");
+
+                       Thread t = Thread.CurrentThread;
+                       CompressedStack original = null;
+                       try {
+                               original = t.GetCompressedStack (); 
+                               t.SetCompressedStack (compressedStack);
+                               callback (state);
+                       }
+                       finally {
+                               if (original != null)
+                                       t.SetCompressedStack (original);
+                       }
+               }
+
+               // internal stuff
+               internal bool Equals (CompressedStack cs)
+               {
+                       if (IsEmpty ())
+                               return cs.IsEmpty ();
+                       if (cs.IsEmpty ())
+                               return false;
+                       if (_list.Count != cs._list.Count)
+                               return false;
+
+                       for (int i=0; i < _list.Count; i++) {
+                               SecurityFrame sf1 = (SecurityFrame) _list [i];
+                               SecurityFrame sf2 = (SecurityFrame) cs._list [i];
+                               if (!sf1.Equals (sf2))
+                                       return false;
+                       }
+                       return true;
+               }
+
+               internal bool IsEmpty ()
+               {
+                       return ((_list == null) || (_list.Count == 0));
+               }
+
+               internal IList List {
+                       get { return _list; }
                }
        }
 }