diff options
Diffstat (limited to 'src/mscorlib/src/System/Threading/Thread.cs')
-rw-r--r-- | src/mscorlib/src/System/Threading/Thread.cs | 251 |
1 files changed, 81 insertions, 170 deletions
diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs index d28002729a..70a5d06f7a 100644 --- a/src/mscorlib/src/System/Threading/Thread.cs +++ b/src/mscorlib/src/System/Threading/Thread.cs @@ -14,7 +14,8 @@ using Internal.Runtime.Augments; -namespace System.Threading { +namespace System.Threading +{ using System.Threading; using System.Runtime; using System.Runtime.InteropServices; @@ -33,11 +34,9 @@ namespace System.Threading { internal class ThreadHelper { - static ThreadHelper() {} - - Delegate _start; - Object _startArg = null; - ExecutionContext _executionContext = null; + private Delegate _start; + private Object _startArg = null; + private ExecutionContext _executionContext = null; internal ThreadHelper(Delegate start) { _start = start; @@ -49,7 +48,7 @@ namespace System.Threading { } static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context); - + static private void ThreadStart_Context(Object state) { ThreadHelper t = (ThreadHelper)state; @@ -65,9 +64,9 @@ namespace System.Threading { // call back helper internal void ThreadStart(object obj) - { + { _startArg = obj; - if (_executionContext != null) + if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } @@ -80,7 +79,7 @@ namespace System.Threading { // call back helper internal void ThreadStart() { - if (_executionContext != null) + if (_executionContext != null) { ExecutionContext.Run(_executionContext, _ccb, (Object)this); } @@ -101,7 +100,7 @@ namespace System.Threading { } } - public sealed class Thread : RuntimeThread + internal sealed class Thread : RuntimeThread { /*========================================================================= ** Data accessed from managed code that needs to be defined in @@ -111,10 +110,10 @@ namespace System.Threading { private ExecutionContext m_ExecutionContext; // this call context follows the logical thread private SynchronizationContext m_SynchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext - private String m_Name; - private Delegate m_Delegate; // Delegate + private String m_Name; + private Delegate m_Delegate; // Delegate - private Object m_ThreadStartArg; + private Object m_ThreadStartArg; /*========================================================================= ** The base implementation of Thread is all native. The following fields @@ -126,10 +125,10 @@ namespace System.Threading { #pragma warning disable 414 // These fields are not used from managed. // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit // fields on 64-bit platforms, where they will be sorted together. - - private IntPtr DONT_USE_InternalThread; // Pointer - private int m_Priority; // INT32 - private int m_ManagedThreadId; // INT32 + + private IntPtr DONT_USE_InternalThread; // Pointer + private int m_Priority; // INT32 + private int m_ManagedThreadId; // INT32 #pragma warning restore 414 #pragma warning restore 169 @@ -143,25 +142,12 @@ namespace System.Threading { // with native code // See code:#threadCultureInfo [ThreadStatic] - internal static CultureInfo m_CurrentCulture; + internal static CultureInfo m_CurrentCulture; [ThreadStatic] - internal static CultureInfo m_CurrentUICulture; - - static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture; - static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture; - - static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args) - { - m_CurrentCulture = args.CurrentValue; - } - - static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<CultureInfo> args) - { - m_CurrentUICulture = args.CurrentValue; - } + internal static CultureInfo m_CurrentUICulture; // Adding an empty default ctor for annotation purposes - internal Thread(){} + internal Thread() { } /*========================================================================= ** Creates a new Thread object which will begin execution at @@ -169,37 +155,45 @@ namespace System.Threading { ** ** Exceptions: ArgumentNullException if start == null. =========================================================================*/ - public Thread(ThreadStart start) { - if (start == null) { + public Thread(ThreadStart start) + { + if (start == null) + { throw new ArgumentNullException(nameof(start)); } Contract.EndContractBlock(); - SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize + SetStartHelper((Delegate)start, 0); //0 will setup Thread with default stackSize } - internal Thread(ThreadStart start, int maxStackSize) { - if (start == null) { + internal Thread(ThreadStart start, int maxStackSize) + { + if (start == null) + { throw new ArgumentNullException(nameof(start)); } if (0 > maxStackSize) - throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(maxStackSize), SR.ArgumentOutOfRange_NeedNonNegNum); Contract.EndContractBlock(); SetStartHelper((Delegate)start, maxStackSize); } - public Thread(ParameterizedThreadStart start) { - if (start == null) { + public Thread(ParameterizedThreadStart start) + { + if (start == null) + { throw new ArgumentNullException(nameof(start)); } Contract.EndContractBlock(); SetStartHelper((Delegate)start, 0); } - internal Thread(ParameterizedThreadStart start, int maxStackSize) { - if (start == null) { + internal Thread(ParameterizedThreadStart start, int maxStackSize) + { + if (start == null) + { throw new ArgumentNullException(nameof(start)); } if (0 > maxStackSize) - throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException(nameof(maxStackSize), SR.ArgumentOutOfRange_NeedNonNegNum); Contract.EndContractBlock(); SetStartHelper((Delegate)start, maxStackSize); } @@ -224,7 +218,7 @@ namespace System.Threading { // There are ways how to create an unitialized objects through remoting, etc. Avoid AVing in the EE by throwing a nice // exception here. if (thread.IsNull()) - throw new ArgumentException(null, Environment.GetResourceString("Argument_InvalidHandle")); + throw new ArgumentException(null, SR.Argument_InvalidHandle); return new ThreadHandle(thread); } @@ -237,24 +231,24 @@ namespace System.Threading { ** ** Exceptions: ThreadStateException if the thread has already been started. =========================================================================*/ - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public new void Start() { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; Start(ref stackMark); } - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod public new void Start(object parameter) { //In the case of a null delegate (second call to start on same thread) // StartInternal method will take care of the error reporting - if(m_Delegate is ThreadStart) + if (m_Delegate is ThreadStart) { //We expect the thread to be setup with a ParameterizedThreadStart // if this constructor is called. //If we got here then that wasn't the case - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart")); + throw new InvalidOperationException(SR.InvalidOperation_ThreadWrongThreadStart); } m_ThreadStartArg = parameter; StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -285,7 +279,7 @@ namespace System.Threading { internal ExecutionContext ExecutionContext { - get { return m_ExecutionContext; } + get { return m_ExecutionContext; } set { m_ExecutionContext = value; } } @@ -320,15 +314,15 @@ namespace System.Threading { { SleepInternal(millisecondsTimeout); // Ensure we don't return to app code when the pause is underway - if(AppDomainPauseManager.IsPaused) + if (AppDomainPauseManager.IsPaused) AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS(); } public static void Sleep(TimeSpan timeout) { long tm = (long)timeout.TotalMilliseconds; - if (tm < -1 || tm > (long) Int32.MaxValue) - throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1")); + if (tm < -1 || tm > (long)Int32.MaxValue) + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); Sleep((int)tm); } @@ -353,9 +347,11 @@ namespace System.Threading { { return YieldInternal(); } - - public static new Thread CurrentThread { - get { + + public static new Thread CurrentThread + { + get + { Contract.Ensures(Contract.Result<Thread>() != null); return GetCurrentThreadNative(); } @@ -368,14 +364,14 @@ namespace System.Threading { Debug.Assert(maxStackSize >= 0); ThreadHelper threadStartCallBack = new ThreadHelper(start); - if(start is ThreadStart) + if (start is ThreadStart) { SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize); } else { SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize); - } + } } /*========================================================================= @@ -437,72 +433,26 @@ namespace System.Threading { // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. - public CultureInfo CurrentUICulture { - get { + public CultureInfo CurrentUICulture + { + get + { Contract.Ensures(Contract.Result<CultureInfo>() != null); -#if FEATURE_APPX && !FEATURE_COREFX_GLOBALIZATION - if(AppDomain.IsAppXModel()) { - return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentUICultureNoAppX(); - } - else -#endif - { - return GetCurrentUICultureNoAppX(); - } + return CultureInfo.CurrentUICulture; } - set { - if (value == null) { - throw new ArgumentNullException(nameof(value)); - } - Contract.EndContractBlock(); - - //If they're trying to use a Culture with a name that we can't use in resource lookup, - //don't even let them set it on the thread. - CultureInfo.VerifyCultureName(value, true); - + set + { // If you add more pre-conditions to this method, check to see if you also need to // add them to CultureInfo.DefaultThreadCurrentUICulture.set. if (m_CurrentUICulture == null && m_CurrentCulture == null) nativeInitCultureAccessors(); - if (!AppContextSwitches.NoAsyncCurrentCulture) - { - if (s_asyncLocalCurrentUICulture == null) - { - Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null); - } - - // this one will set m_CurrentUICulture too - s_asyncLocalCurrentUICulture.Value = value; - } - else - { - m_CurrentUICulture = value; - } + CultureInfo.CurrentUICulture = value; } } - internal CultureInfo GetCurrentUICultureNoAppX() { - - Contract.Ensures(Contract.Result<CultureInfo>() != null); - -#if FEATURE_COREFX_GLOBALIZATION - return CultureInfo.CurrentUICulture; -#else - - // Fetch a local copy of m_CurrentUICulture to - // avoid race conditions that malicious user can introduce - if (m_CurrentUICulture == null) { - CultureInfo appDomainDefaultUICulture = CultureInfo.DefaultThreadCurrentUICulture; - return (appDomainDefaultUICulture != null ? appDomainDefaultUICulture : CultureInfo.UserDefaultUICulture); - } - - return m_CurrentUICulture; -#endif - } - // This returns the exposed context for a given context ID. // As the culture can be customized object then we cannot hold any @@ -517,25 +467,16 @@ namespace System.Threading { // app domain get unloaded there is a code to clean up the culture from the thread // using the code in AppDomain::ReleaseDomainStores. - public CultureInfo CurrentCulture { - get { + public CultureInfo CurrentCulture + { + get + { Contract.Ensures(Contract.Result<CultureInfo>() != null); - -#if FEATURE_APPX && !FEATURE_COREFX_GLOBALIZATION - if(AppDomain.IsAppXModel()) { - return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentCultureNoAppX(); - } - else -#endif - { - return GetCurrentCultureNoAppX(); - } + return CultureInfo.CurrentCulture; } - set { - if (null==value) { - throw new ArgumentNullException(nameof(value)); - } + set + { Contract.EndContractBlock(); // If you add more pre-conditions to this method, check to see if you also need to @@ -543,39 +484,9 @@ namespace System.Threading { if (m_CurrentCulture == null && m_CurrentUICulture == null) nativeInitCultureAccessors(); - - if (!AppContextSwitches.NoAsyncCurrentCulture) - { - if (s_asyncLocalCurrentCulture == null) - { - Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null); - } - // this one will set m_CurrentCulture too - s_asyncLocalCurrentCulture.Value = value; - } - else - { - m_CurrentCulture = value; - } - } - } - - private CultureInfo GetCurrentCultureNoAppX() { - -#if FEATURE_COREFX_GLOBALIZATION - return CultureInfo.CurrentCulture; -#else - Contract.Ensures(Contract.Result<CultureInfo>() != null); - - // Fetch a local copy of m_CurrentCulture to - // avoid race conditions that malicious user can introduce - if (m_CurrentCulture == null) { - CultureInfo appDomainDefaultCulture = CultureInfo.DefaultThreadCurrentCulture; - return (appDomainDefaultCulture != null ? appDomainDefaultCulture : CultureInfo.UserDefaultCulture); + + CultureInfo.CurrentCulture = value; } - - return m_CurrentCulture; -#endif } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] @@ -616,14 +527,18 @@ namespace System.Threading { // Retrieves the name of the thread. // - public new String Name { - get { + public new String Name + { + get + { return m_Name; } - set { - lock(this) { + set + { + lock (this) + { if (m_Name != null) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce")); + throw new InvalidOperationException(SR.InvalidOperation_WriteOnce); m_Name = value; InformThreadNameChange(GetNativeHandle(), value, (value != null) ? value.Length : 0); @@ -635,9 +550,6 @@ namespace System.Threading { [SuppressUnmanagedCodeSecurity] private static extern void InformThreadNameChange(ThreadHandle t, String name, int len); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - public static extern void MemoryBarrier(); - } // End of class Thread // declaring a local var of this enum type and passing it by ref into a function that needs to do a @@ -651,5 +563,4 @@ namespace System.Threading { LookForMyCallersCaller = 2, LookForThread = 3 } - } |