Warnings cleanup
[mono.git] / mcs / class / corlib / System.Threading / Thread.cs
index f1aec3662c6fbd22b0e11f5d7ddd2a2cc1713d70..a1e44a48687c96ef299957aa37fc8404f37c9795 100644 (file)
@@ -54,6 +54,7 @@ namespace System.Threading {
        public sealed class Thread : _Thread {
 #endif
 
+#pragma warning disable 169, 414, 649
                #region Sync with metadata/object-internals.h
                int lock_thread_id;
                // stores a thread handle
@@ -84,12 +85,11 @@ namespace System.Threading {
                int stack_size;
                object start_obj;
                private IntPtr appdomain_refs;
-               private bool interruption_requested;
+               private int interruption_requested;
                private IntPtr suspend_event;
                private IntPtr suspended_event;
                private IntPtr resume_event;
-               /* Don't lock on synch_cs in managed code, since it can result in deadlocks */
-               private object synch_cs = null;
+               private IntPtr synch_cs;
                private IntPtr serialized_culture_info;
                private int serialized_culture_info_len;
                private IntPtr serialized_ui_culture_info;
@@ -99,14 +99,21 @@ namespace System.Threading {
                private IntPtr end_stack;
                private bool thread_interrupt_requested;
                private byte apartment_state = (byte)ApartmentState.Unknown;
+               volatile int critical_region_level;
+               private int small_id;
+               private IntPtr manage_callback;
+               private object pending_exception;
                /* 
                 * These fields are used to avoid having to increment corlib versions
                 * when a new field is added to the unmanaged MonoThread structure.
                 */
+               private IntPtr unused2;
+               private IntPtr unused3;
+               private IntPtr unused4;
                private IntPtr unused5;
                private IntPtr unused6;
-               private IntPtr unused7;
                #endregion
+#pragma warning restore 169, 414, 649
 
                // the name of local_slots is important as it's used by the runtime.
                [ThreadStatic] 
@@ -114,12 +121,15 @@ namespace System.Threading {
 
                // can be both a ThreadSart and a ParameterizedThreadStart
                private MulticastDelegate threadstart;
-               private string thread_name=null;
-               
+               //private string thread_name=null;
+
+#if NET_2_0            
                private static int _managed_id_counter;
                private int managed_id;
+#endif         
                
                private IPrincipal _principal;
+               internal NumberFormatter _numberFormatter;
 
                public static Context CurrentContext {
                        [SecurityPermission (SecurityAction.LinkDemand, Infrastructure=true)]
@@ -238,6 +248,18 @@ namespace System.Threading {
                        slots [slot.slot] = data;
                }
 
+               internal NumberFormatter AcquireNumberFormatter() {
+                       NumberFormatter res = _numberFormatter;
+                       _numberFormatter = null;
+                       if (res == null)
+                               return new NumberFormatter (this);
+                       return res;
+               }
+
+               internal void ReleaseNumberFormatter (NumberFormatter formatter) {
+                       _numberFormatter = formatter;
+               }
+
                public static AppDomain GetDomain() {
                        return AppDomain.CurrentDomain;
                }
@@ -299,10 +321,6 @@ namespace System.Threading {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern void Thread_init ();
 
-               private static int GetNewManagedId() {
-                       return Interlocked.Increment(ref _managed_id_counter);
-               }
-
                public Thread(ThreadStart start) {
                        if(start==null) {
                                throw new ArgumentNullException("Null ThreadStart");
@@ -327,11 +345,16 @@ namespace System.Threading {
 #if NET_2_0
                                TrySetApartmentState (value);
 #else
-                               if ((ThreadState & ThreadState.Unstarted) == 0)
+                               /* Only throw this exception when
+                                * changing the state of another
+                                * thread.  See bug 324338
+                                */
+                               if ((this != CurrentThread) &&
+                                   (ThreadState & ThreadState.Unstarted) == 0)
                                        throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
 
                                if (value != ApartmentState.STA && value != ApartmentState.MTA)
-                                       throw new ArgumentException ("value is not a valid apartment state.");
+                                       throw new ArgumentOutOfRangeException ("value is not a valid apartment state.");
 
                                if ((ApartmentState)apartment_state == ApartmentState.Unknown)
                                        apartment_state = (byte)value;
@@ -339,8 +362,8 @@ namespace System.Threading {
                        }
                }
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private static extern int current_lcid ();
+               //[MethodImplAttribute (MethodImplOptions.InternalCall)]
+               //private static extern int current_lcid ();
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern CultureInfo GetCachedCurrentCulture ();
@@ -372,7 +395,7 @@ namespace System.Threading {
                 * CurrentCulture, which will throw an exception, etc.
                 * Use a boolean to short-circuit this scenario.
                 */
-               private static bool in_currentculture=false;
+               private bool in_currentculture=false;
 
                static object culture_lock = new object ();
                
@@ -407,6 +430,8 @@ namespace System.Threading {
                                                //
                                                SetCachedCurrentCulture (culture);
                                                in_currentculture = false;
+                                               if (_numberFormatter != null)
+                                                       _numberFormatter.CurrentCulture = culture;
                                                return culture;
                                        }
                                }
@@ -425,6 +450,8 @@ namespace System.Threading {
                                        in_currentculture = false;
                                }
 
+                               if (_numberFormatter != null)
+                                       _numberFormatter.CurrentCulture = culture;
                                return culture;
                        }
                        
@@ -433,18 +460,35 @@ namespace System.Threading {
                                if (value == null)
                                        throw new ArgumentNullException ("value");
 
+                               CultureInfo culture = GetCachedCurrentCulture ();
+                               if (culture == value)
+                                       return;
+
                                value.CheckNeutral ();
                                in_currentculture = true;
                                try {
-                                       BinaryFormatter bf = new BinaryFormatter();
-                                       MemoryStream ms = new MemoryStream ();
-                                       bf.Serialize (ms, value);
-
                                        SetCachedCurrentCulture (value);
-                                       SetSerializedCurrentCulture (ms.GetBuffer ());
+
+                                       byte[] serialized_form = null;
+
+                                       if (value.IsReadOnly && value.cached_serialized_form != null) {
+                                               serialized_form = value.cached_serialized_form;
+                                       } else {
+                                               BinaryFormatter bf = new BinaryFormatter();
+                                               MemoryStream ms = new MemoryStream ();
+                                               bf.Serialize (ms, value);
+
+                                               serialized_form = ms.GetBuffer ();
+                                               if (value.IsReadOnly)
+                                                       value.cached_serialized_form = serialized_form;
+                                       }
+                                               
+                                       SetSerializedCurrentCulture (serialized_form);
                                } finally {
                                        in_currentculture = false;
                                }
+                               if (_numberFormatter != null)
+                                       _numberFormatter.CurrentCulture = value;
                        }
                }
 
@@ -504,13 +548,28 @@ namespace System.Threading {
                                if (value == null)
                                        throw new ArgumentNullException ("value");
 
-                               try {
-                                       BinaryFormatter bf = new BinaryFormatter();
-                                       MemoryStream ms = new MemoryStream ();
-                                       bf.Serialize (ms, value);
+                               CultureInfo culture = GetCachedCurrentUICulture ();
+                               if (culture == value)
+                                       return;
 
+                               try {
                                        SetCachedCurrentUICulture (value);
-                                       SetSerializedCurrentUICulture (ms.GetBuffer ());
+
+                                       byte[] serialized_form = null;
+
+                                       if (value.IsReadOnly && value.cached_serialized_form != null) {
+                                               serialized_form = value.cached_serialized_form;
+                                       } else {
+                                               BinaryFormatter bf = new BinaryFormatter();
+                                               MemoryStream ms = new MemoryStream ();
+                                               bf.Serialize (ms, value);
+
+                                               serialized_form = ms.GetBuffer ();
+                                               if (value.IsReadOnly)
+                                                       value.cached_serialized_form = serialized_form;
+                                       }
+                                               
+                                       SetSerializedCurrentUICulture (serialized_form);
                                } finally {
                                        in_currentculture = false;
                                }
@@ -828,6 +887,10 @@ namespace System.Threading {
 #endif
 
 #if NET_2_0
+               private static int GetNewManagedId() {
+                       return Interlocked.Increment(ref _managed_id_counter);
+               }
+
                public Thread (ThreadStart start, int maxStackSize)
                {
                        if (start == null)
@@ -837,6 +900,7 @@ namespace System.Threading {
 
                        threadstart = start;
                        stack_size = maxStackSize;
+                       Thread_init ();
                }
 
                public Thread (ParameterizedThreadStart start)
@@ -845,6 +909,7 @@ namespace System.Threading {
                                throw new ArgumentNullException ("start");
 
                        threadstart = start;
+                       Thread_init ();
                }
 
                public Thread (ParameterizedThreadStart start, int maxStackSize)
@@ -856,6 +921,7 @@ namespace System.Threading {
 
                        threadstart = start;
                        stack_size = maxStackSize;
+                       Thread_init ();
                }
 
                [MonoTODO ("limited to CompressedStack support")]
@@ -882,32 +948,28 @@ namespace System.Threading {
                        }
                }
 
-               [MonoTODO("Not implemented")]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
                public static void BeginCriticalRegion ()
                {
-                       throw new NotImplementedException ();
+                       CurrentThread.critical_region_level++;
                }
 
-               [MonoTODO("Not implemented")]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public static void EndCriticalRegion ()
                {
-                       throw new NotImplementedException ();
+                       CurrentThread.critical_region_level--;
                }
 
-               [MonoTODO("Not implemented")]
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
                public static void BeginThreadAffinity ()
                {
-                       throw new NotImplementedException ();
+                       // Managed and native threads are currently bound together.
                }
 
-               [MonoTODO("Not implemented")]
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
                public static void EndThreadAffinity ()
                {
-                       throw new NotImplementedException ();
+                       // Managed and native threads are currently bound together.
                }
                
                public ApartmentState GetApartmentState ()
@@ -923,7 +985,11 @@ namespace System.Threading {
 
                public bool TrySetApartmentState (ApartmentState state) 
                {
-                       if ((ThreadState & ThreadState.Unstarted) == 0)
+                       /* Only throw this exception when changing the
+                        * state of another thread.  See bug 324338
+                        */
+                       if ((this != CurrentThread) &&
+                           (ThreadState & ThreadState.Unstarted) == 0)
                                throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
 
                        if ((ApartmentState)apartment_state != ApartmentState.Unknown)