2006-07-04 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / System.Threading / Thread.cs
index 7d8caa9b13df4c9f03b0f9cb38f0239922f75ca2..75321e536a7041ad8267bea2412464eeed65b7c9 100644 (file)
@@ -49,16 +49,19 @@ namespace System.Threading {
 #if NET_2_0
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_Thread))]
-#endif
+       public sealed class Thread : CriticalFinalizerObject, _Thread {
+#else
        public sealed class Thread : _Thread {
+#endif
 
                #region Sync with metadata/object-internals.h
                int lock_thread_id;
                // stores a thread handle
                private IntPtr system_thread_handle;
-               
-               private IntPtr culture_info;
-               private IntPtr ui_culture_info;
+
+               /* Note this is an opaque object (an array), not a CultureInfo */
+               private object cached_culture_info;
+               private IntPtr unused0;
                private bool threadpool_thread;
                /* accessed only from unmanaged code */
                private IntPtr name;
@@ -105,8 +108,9 @@ namespace System.Threading {
                private IntPtr unused7;
                #endregion
 
+               // the name of local_slots is important as it's used by the runtime.
                [ThreadStatic] 
-               static Hashtable slothash;
+               static object[] local_slots;
 
                // can be both a ThreadSart and a ParameterizedThreadStart
                private MulticastDelegate threadstart;
@@ -171,56 +175,64 @@ namespace System.Threading {
                        }
                }
                
-               public static LocalDataStoreSlot AllocateNamedDataSlot(string name) {
+               public static LocalDataStoreSlot AllocateNamedDataSlot (string name) {
                        lock (datastore_lock) {
                                if (datastorehash == null)
                                        InitDataStoreHash ();
-                               LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash[name];
-                               if(slot!=null) {
+                               LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash [name];
+                               if (slot != null) {
                                        // This exception isnt documented (of
                                        // course) but .net throws it
                                        throw new ArgumentException("Named data slot already added");
                                }
                        
-                               slot = new LocalDataStoreSlot();
+                               slot = AllocateDataSlot ();
 
-                               datastorehash.Add(name, slot);
+                               datastorehash.Add (name, slot);
 
-                               return(slot);
+                               return slot;
                        }
                }
 
-               public static void FreeNamedDataSlot(string name) {
+               public static void FreeNamedDataSlot (string name) {
                        lock (datastore_lock) {
                                if (datastorehash == null)
                                        InitDataStoreHash ();
-                               LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
+                               LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash [name];
 
-                               if(slot!=null) {
-                                       datastorehash.Remove(slot);
+                               if (slot != null) {
+                                       datastorehash.Remove (slot);
                                }
                        }
                }
 
-               private static Hashtable SlotHash {
-                       get {
-                               if (slothash == null)
-                                       slothash = new Hashtable ();
-                               return slothash;
-                       }
-               }
-
-               public static LocalDataStoreSlot AllocateDataSlot() {
-                       return new LocalDataStoreSlot();
+               public static LocalDataStoreSlot AllocateDataSlot () {
+                       return new LocalDataStoreSlot (true);
                }
 
-               public static object GetData(LocalDataStoreSlot slot) {
-                       return SlotHash [slot];
+               public static object GetData (LocalDataStoreSlot slot) {
+                       object[] slots = local_slots;
+                       if (slot == null)
+                               throw new ArgumentNullException ("slot");
+                       if (slots != null && slot.slot < slots.Length)
+                               return slots [slot.slot];
+                       return null;
                }
 
-               public static void SetData(LocalDataStoreSlot slot,
-                                          object data) {
-                       SlotHash [slot] = data;
+               public static void SetData (LocalDataStoreSlot slot, object data) {
+                       object[] slots = local_slots;
+                       if (slot == null)
+                               throw new ArgumentNullException ("slot");
+                       if (slots == null) {
+                               slots = new object [slot.slot + 2];
+                               local_slots = slots;
+                       } else if (slot.slot >= slots.Length) {
+                               object[] nslots = new object [slot.slot + 2];
+                               slots.CopyTo (nslots, 0);
+                               slots = nslots;
+                               local_slots = slots;
+                       }
+                       slots [slot.slot] = data;
                }
 
                public static AppDomain GetDomain() {
@@ -230,6 +242,9 @@ namespace System.Threading {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static int GetDomainID();
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void FreeLocalSlotValues (int slot, bool thread_local);
+
                public static LocalDataStoreSlot GetNamedDataSlot(string name) {
                        lock (datastore_lock) {
                                if (datastorehash == null)
@@ -576,6 +591,7 @@ namespace System.Threading {
                [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
                public void Interrupt ()
                {
+                       throw new NotImplementedException ();
                }
 
                // The current thread joins with 'this'. Set ms to 0 to block
@@ -608,11 +624,8 @@ namespace System.Threading {
                }
 
 #if NET_1_1
-               [MonoTODO ("seems required for multi-processors systems like Itanium")]
-               public static void MemoryBarrier ()
-               {
-                       // Will be implemented when we support Itanium
-               }
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern static void MemoryBarrier ();
 #endif
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern void Resume_internal();
@@ -646,6 +659,8 @@ namespace System.Threading {
                        if (SecurityManager.SecurityEnabled)
                                _ec = ExecutionContext.Capture ();
 #endif
+                       if (CurrentThread._principal != null)
+                               _principal = CurrentThread._principal;
 
                        // Thread_internal creates and starts the new thread, 
                        if (Thread_internal(threadstart) == (IntPtr) 0)
@@ -668,6 +683,9 @@ namespace System.Threading {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern void Thread_free_internal(IntPtr handle);
 
+#if NET_2_0
+               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
+#endif
                ~Thread() {
                        // Free up the handle
                        if (system_thread_handle != (IntPtr) 0)
@@ -913,6 +931,9 @@ namespace System.Threading {
                // But it's there!
                [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
                [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
+#if NET_2_0
+               [Obsolete ("see CompressedStack class")]
+#endif
 #if NET_1_1
                public
 #else
@@ -932,6 +953,9 @@ namespace System.Threading {
                // But it's there!
                [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
                [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
+#if NET_2_0
+               [Obsolete ("see CompressedStack class")]
+#endif
 #if NET_1_1
                public
 #else