namespace System.Threading {
[StructLayout (LayoutKind.Sequential)]
- internal class InternalThread : CriticalFinalizerObject {
+ sealed class InternalThread : CriticalFinalizerObject {
#pragma warning disable 169, 414, 649
#region Sync with metadata/object-internals.h
int lock_thread_id;
IPrincipal principal;
int principal_version;
+ bool current_culture_set;
+ bool current_ui_culture_set;
CultureInfo current_culture;
CultureInfo current_ui_culture;
static NamedDataSlot namedDataSlot;
+ static internal CultureInfo default_culture;
+ static internal CultureInfo default_ui_culture;
+
// can be both a ThreadStart and a ParameterizedThreadStart
private MulticastDelegate threadstart;
//private string thread_name=null;
ResetAbort_internal ();
}
-#if NET_4_0
[HostProtectionAttribute (SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
public extern static bool Yield ();
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public CultureInfo CurrentCulture {
get {
CultureInfo culture = current_culture;
- if (culture != null)
+ if (current_culture_set && culture != null)
return culture;
+ if (default_culture != null)
+ return default_culture;
+
current_culture = culture = CultureInfo.ConstructCurrentCulture ();
- NumberFormatter.SetThreadCurrentCulture (culture);
return culture;
}
value.CheckNeutral ();
current_culture = value;
- NumberFormatter.SetThreadCurrentCulture (value);
+ current_culture_set = true;
}
}
public CultureInfo CurrentUICulture {
get {
CultureInfo culture = current_ui_culture;
- if (culture != null)
+ if (current_ui_culture_set && culture != null)
return culture;
+ if (default_ui_culture != null)
+ return default_ui_culture;
+
current_ui_culture = culture = CultureInfo.ConstructCurrentUICulture ();
return culture;
}
if (value == null)
throw new ArgumentNullException ("value");
current_ui_culture = value;
+ current_ui_culture_set = true;
}
}
public ThreadPriority Priority {
get {
- return(ThreadPriority.Lowest);
+ return (ThreadPriority)GetPriority (Internal);
}
set {
- // FIXME: Implement setter.
+ // FIXME: This doesn't do anything yet
+ SetPriority (Internal, (int)value);
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void Abort_internal (InternalThread thread, object stateInfo);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static int GetPriority (InternalThread thread);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static void SetPriority (InternalThread thread, int priority);
+
[SecurityPermission (SecurityAction.Demand, ControlThread=true)]
public void Abort ()
{
public void Start() {
// propagate informations from the original thread to the new thread
- if (!ExecutionContext.IsFlowSuppressed ())
- ec_to_set = ExecutionContext.Capture ();
+ ec_to_set = ExecutionContext.Capture (false, true);
Internal._serialized_principal = CurrentThread.Internal._serialized_principal;
// Thread_internal creates and starts the new thread,
[MethodImplAttribute (MethodImplOptions.InternalCall)]
extern public static void VolatileWrite (ref UIntPtr address, UIntPtr value);
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ extern static int SystemMaxStackStize ();
static int CheckStackSize (int maxStackSize)
{
if ((maxStackSize % page_size) != 0) // round up to a divisible of page size
maxStackSize = (maxStackSize / (page_size - 1)) * page_size;
- int default_stack_size = (IntPtr.Size / 4) * 1024 * 1024; // from wthreads.c
-
- if (maxStackSize > default_stack_size)
- return default_stack_size;
-
- return maxStackSize;
+ /* Respect the max stack size imposed by the system*/
+ return Math.Min (maxStackSize, SystemMaxStackStize ());
}
public Thread (ThreadStart start, int maxStackSize)
Internal.stack_size = CheckStackSize (maxStackSize);
}
- [MonoTODO ("limited to CompressedStack support")]
public ExecutionContext ExecutionContext {
[ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
get {
_ec = new ExecutionContext ();
return _ec;
}
+ internal set {
+ _ec = value;
+ }
+ }
+
+ internal bool HasExecutionContext {
+ get {
+ return _ec != null;
+ }
+ }
+
+ internal void BranchExecutionContext (out ExecutionContext.Switcher switcher)
+ {
+ if (_ec == null) {
+ switcher = new ExecutionContext.Switcher ();
+ } else {
+ switcher = new ExecutionContext.Switcher (_ec);
+ _ec.CopyOnWrite = true;
+ }
+ }
+
+ internal void RestoreExecutionContext (ref ExecutionContext.Switcher switcher)
+ {
+ if (switcher.IsEmpty) {
+ _ec = null;
+ return;
+ }
+
+ switcher.Restore (_ec);
}
public int ManagedThreadId {
public bool TrySetApartmentState (ApartmentState state)
{
- /* Only throw this exception when changing the
- * state of another thread. See bug 324338
- */
- if ((this != CurrentThread) &&
- (ThreadState & ThreadState.Unstarted) == 0)
+ if ((ThreadState & ThreadState.Unstarted) == 0)
throw new ThreadStateException ("Thread was in an invalid state for the operation being executed.");
if ((ApartmentState)Internal.apartment_state != ApartmentState.Unknown &&
throw new NotImplementedException ();
}
#endif
+
+ internal CultureInfo GetCurrentUICultureNoAppX ()
+ {
+ return CultureInfo.CurrentUICulture;
+ }
}
}