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
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;
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]
// 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)]
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;
}
[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");
#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;
}
}
- [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 ();
* 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 ();
//
SetCachedCurrentCulture (culture);
in_currentculture = false;
+ if (_numberFormatter != null)
+ _numberFormatter.CurrentCulture = culture;
return culture;
}
}
in_currentculture = false;
}
+ if (_numberFormatter != null)
+ _numberFormatter.CurrentCulture = culture;
return culture;
}
} finally {
in_currentculture = false;
}
+ if (_numberFormatter != null)
+ _numberFormatter.CurrentCulture = value;
}
}
#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)
}
}
- [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 ()
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)