Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / Threading / Thread.cs / 6 / Thread.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*==============================================================================
**
** Class: Thread
**
**
** Purpose: Class for creating and managing a thread.
**
**
=============================================================================*/
namespace System.Threading {
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System;
using System.Diagnostics;
using System.Security.Permissions;
using System.Security.Principal;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.Runtime.Versioning;
internal delegate Object InternalCrossContextDelegate(Object[] args);
internal class ThreadHelper
{
Delegate _start;
Object _startArg = null;
ExecutionContext _executionContext = null;
internal ThreadHelper(Delegate start)
{
_start = start;
}
internal void SetExecutionContextHelper(ExecutionContext ec)
{
_executionContext = ec;
}
static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
static internal void ThreadStart_Context(Object state)
{
ThreadHelper t = (ThreadHelper)state;
if (t._start is ThreadStart)
{
((ThreadStart)t._start)();
}
else
{
((ParameterizedThreadStart)t._start)(t._startArg);
}
}
// call back helper
internal void ThreadStart(object obj)
{
_startArg = obj;
if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
else
{
((ParameterizedThreadStart)_start)(obj);
}
}
// call back helper
internal void ThreadStart()
{
if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
else
{
((ThreadStart)_start)();
}
}
};
// deliberately not [serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Thread))]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Thread : CriticalFinalizerObject, _Thread
{
/*=========================================================================
** Data accessed from managed code that needs to be defined in
** ThreadBaseObject to maintain alignment between the two classes.
** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h
=========================================================================*/
private Context m_Context;
private ExecutionContext m_ExecutionContext; // this call context follows the logical thread
private String m_Name;
private Delegate m_Delegate; // Delegate
private Object[][] m_ThreadStaticsBuckets; // Holder for thread statics
private int[] m_ThreadStaticsBits; // Bit-markers for slot availability
private CultureInfo m_CurrentCulture;
private CultureInfo m_CurrentUICulture;
#if IO_CANCELLATION_ENABLED
internal List m_CancellationSignals; // IO Cancellation stack
#endif
private Object m_ThreadStartArg;
/*=========================================================================
** The base implementation of Thread is all native. The following fields
** should never be used in the C# code. They are here to define the proper
** space so the thread object may be allocated. DON'T CHANGE THESE UNLESS
** YOU MODIFY ThreadBaseObject in vm\object.h
=========================================================================*/
#pragma warning disable 169
#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
#pragma warning restore 414
#pragma warning restore 169
/*=========================================================================
** This manager is responsible for storing the global data that is
** shared amongst all the thread local stores.
=========================================================================*/
static private LocalDataStoreMgr s_LocalDataStoreMgr = null;
static private Object s_SyncObject = new Object();
// Has to be in [....] with THREAD_STATICS_BUCKET_SIZE in vm/threads.cpp
private const int STATICS_BUCKET_SIZE = 32;
/*==========================================================================
** Creates a new Thread object which will begin execution at
** start.ThreadStart on a new thread when the Start method is called.
**
** Exceptions: ArgumentNullException if start == null.
=========================================================================*/
public Thread(ThreadStart start) {
if (start == null) {
throw new ArgumentNullException("start");
}
SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize
}
public Thread(ThreadStart start, int maxStackSize) {
if (start == null) {
throw new ArgumentNullException("start");
}
if (0 > maxStackSize)
throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
SetStartHelper((Delegate)start, maxStackSize);
}
public Thread(ParameterizedThreadStart start) {
if (start == null) {
throw new ArgumentNullException("start");
}
SetStartHelper((Delegate)start, 0);
}
public Thread(ParameterizedThreadStart start, int maxStackSize) {
if (start == null) {
throw new ArgumentNullException("start");
}
if (0 > maxStackSize)
throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
SetStartHelper((Delegate)start, maxStackSize);
}
[ComVisible(false),
MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override int GetHashCode();
public int ManagedThreadId
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
return m_ManagedThreadId;
}
}
/*=========================================================================
** Spawns off a new thread which will begin executing at the ThreadStart
** method on the IThreadable interface passed in the constructor. Once the
** thread is dead, it cannot be restarted with another call to Start.
**
** Exceptions: ThreadStateException if the thread has already been started.
=========================================================================*/
[HostProtection(Synchronization=true,ExternalThreading=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Start()
{
#if FEATURE_COMINTEROP
// Eagerly initialize the COM Apartment state of the thread if we're allowed to.
StartupSetApartmentStateInternal();
#endif // FEATURE_COMINTEROP
// Attach current thread's security principal object to the new
// thread. Be careful not to bind the current thread to a principal
// if it's not already bound.
if (m_Delegate != null)
{
// If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of
// reporting an error. Just make sure we dont try to dereference a null delegate.
ThreadHelper t = (ThreadHelper)(m_Delegate.Target);
ExecutionContext ec = ExecutionContext.Capture();
ExecutionContext.ClearSyncContext(ec);
t.SetExecutionContextHelper(ec);
}
IPrincipal principal = (IPrincipal) CallContext.Principal;
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
StartInternal(principal, ref stackMark);
}
[HostProtection(Synchronization=true,ExternalThreading=true)]
public 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)
{
//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"));
}
m_ThreadStartArg = parameter;
Start();
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal ExecutionContext GetExecutionContextNoCreate()
{
return m_ExecutionContext;
}
public ExecutionContext ExecutionContext
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get
{
if (m_ExecutionContext == null && this == Thread.CurrentThread)
{
m_ExecutionContext = new ExecutionContext();
m_ExecutionContext.Thread = this;
}
return m_ExecutionContext;
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal void SetExecutionContext(ExecutionContext value) {
m_ExecutionContext = value;
if (value != null)
m_ExecutionContext.Thread = this;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark);
///
[StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"),
SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode),
DynamicSecurityMethodAttribute()]
[Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public void SetCompressedStack( CompressedStack stack )
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
}
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle);
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern void RestoreAppDomainStack( IntPtr appDomainStack);
///
[StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"),
SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
[Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public CompressedStack GetCompressedStack()
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
}
// Helper method to get a logical thread ID for StringBuilder (for
// correctness) and for FileStream's async code path (for perf, to
// avoid creating a Thread instance).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static IntPtr InternalGetCurrentThread();
#if IO_CANCELLATION_ENABLED
// Internal method to get the OS thread handle for this thread.
internal extern IntPtr Handle {
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
#endif
/*==========================================================================
** Raises a ThreadAbortException in the thread, which usually
** results in the thread's death. The ThreadAbortException is a special
** exception that is not catchable. The finally clauses of all try
** statements will be executed before the thread dies. This includes the
** finally that a thread might be executing at the moment the Abort is raised.
** The thread is not stopped immediately--you must Join on the
** thread to guarantee it has stopped.
** It is possible for a thread to do an unbounded amount of computation in
** the finally's and thus indefinitely delay the threads death.
** If Abort() is called on a thread that has not been started, the thread
** will abort when Start() is called.
** If Abort is called twice on the same thread, a DuplicateThreadAbort
** exception is thrown.
=========================================================================*/
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public void Abort(Object stateInfo)
{
// If two aborts come at the same time, it is possible that the state info
// gets set by one, and the actual abort gets delivered by another. But this
// is not distinguishable by an application.
// The accessor helper will only set the value if it isn't already set,
// and that particular bit of native code can test much faster than this
// code could, because testing might cause a cross-appdomain marshalling.
AbortReason = stateInfo;
// Note: we demand ControlThread permission, then call AbortInternal directly
// rather than delegating to the Abort() function below. We do this to ensure
// that only callers with ControlThread are allowed to change the AbortReason
// of the thread. We call AbortInternal directly to avoid demanding the same
// permission twice.
AbortInternal();
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public void Abort() { AbortInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();
/*==========================================================================
** Resets a thread abort.
** Should be called by trusted code only
=========================================================================*/
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public static void ResetAbort()
{
Thread thread = Thread.CurrentThread;
if ((thread.ThreadState & ThreadState.AbortRequested) == 0)
throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested"));
thread.ResetAbortNative();
thread.ClearAbortReason();
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void ResetAbortNative();
/*=========================================================================
** Suspends the thread. If the thread is already suspended, this call has
** no effect.
**
** Exceptions: ThreadStateException if the thread has not been started or
** it is dead.
=========================================================================*/
[Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)]
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Suspend() { SuspendInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SuspendInternal();
/*==========================================================================
** Resumes a thread that has been suspended.
**
** Exceptions: ThreadStateException if the thread has not been started or
** it is dead or it isn't in the suspended state.
=========================================================================*/
[Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)]
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Resume() { ResumeInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void ResumeInternal();
/*=========================================================================
** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that
** thread is not currently blocked in that manner, it will be interrupted
** when it next begins to block.
=========================================================================*/
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Interrupt() { InterruptInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InterruptInternal();
/*=========================================================================
** Returns the priority of the thread.
**
** Exceptions: ThreadStateException if the thread is dead.
=========================================================================*/
public ThreadPriority Priority {
get { return (ThreadPriority)GetPriorityNative(); }
[HostProtection(SelfAffectingThreading=true)]
set { SetPriorityNative((int)value); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetPriorityNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetPriorityNative(int priority);
/*=========================================================================
** Returns true if the thread has been started and is not dead.
=========================================================================*/
public bool IsAlive {
get { return IsAliveNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsAliveNative();
/*==========================================================================
** Returns true if the thread is a threadpool thread.
=========================================================================*/
public bool IsThreadPoolThread {
get { return IsThreadpoolThreadNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsThreadpoolThreadNative();
/*=========================================================================
** Waits for the thread to die.
**
** Exceptions: ThreadInterruptedException if the thread is interrupted while waiting.
** ThreadStateException if the thread has not been started yet.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[HostProtection(Synchronization=true, ExternalThreading=true)]
private extern void JoinInternal();
[HostProtection(Synchronization=true, ExternalThreading=true)]
public void Join()
{
JoinInternal();
}
/*==========================================================================
** Waits for the thread to die or for timeout milliseconds to elapse.
** Returns true if the thread died, or false if the wait timed out. If
** Timeout.Infinite is given as the parameter, no timeout will occur.
**
** Exceptions: ArgumentException if timeout < 0.
** ThreadInterruptedException if the thread is interrupted while waiting.
** ThreadStateException if the thread has not been started yet.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[HostProtection(Synchronization=true, ExternalThreading=true)]
private extern bool JoinInternal(int millisecondsTimeout);
[HostProtection(Synchronization=true, ExternalThreading=true)]
public bool Join(int millisecondsTimeout)
{
return JoinInternal(millisecondsTimeout);
}
[HostProtection(Synchronization=true, ExternalThreading=true)]
public bool Join(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return Join((int)tm);
}
/*==========================================================================
** Suspends the current thread for timeout milliseconds. If timeout == 0,
** forces the thread to give up the remainer of its timeslice. If timeout
** == Timeout.Infinite, no timeout will occur.
**
** Exceptions: ArgumentException if timeout < 0.
** ThreadInterruptedException if the thread is interrupted while sleeping.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);
public static void Sleep(int millisecondsTimeout)
{
SleepInternal(millisecondsTimeout);
}
public static void Sleep(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Sleep((int)tm);
}
/* wait for a length of time proportial to 'iterations'. Each iteration is should
only take a few machine instructions. Calling this API is preferable to coding
a explict busy loop because the hardware can be informed that it is busy waiting. */
[MethodImplAttribute(MethodImplOptions.InternalCall),
HostProtection(Synchronization=true,ExternalThreading=true),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern void SpinWaitInternal(int iterations);
[HostProtection(Synchronization=true,ExternalThreading=true),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void SpinWait(int iterations)
{
SpinWaitInternal(iterations);
}
public static Thread CurrentThread {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get {
Thread th;
th = GetFastCurrentThreadNative();
if (th == null)
th = GetCurrentThreadNative();
return th;
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern Thread GetCurrentThreadNative();
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern Thread GetFastCurrentThreadNative();
private void SetStartHelper(Delegate start, int maxStackSize)
{
ThreadHelper threadStartCallBack = new ThreadHelper(start);
if(start is ThreadStart)
{
SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
}
else
{
SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
}
}
/*=========================================================================
** PRIVATE Sets the IThreadable interface for the thread. Assumes that
** start != null.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetStart(Delegate start, int maxStackSize);
/*==========================================================================
** Clean up the thread when it goes away.
=========================================================================*/
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~Thread()
{
// Delegate to the unmanaged portion.
InternalFinalize();
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InternalFinalize();
/*=========================================================================
** Return whether or not this thread is a background thread. Background
** threads do not affect when the Execution Engine shuts down.
**
** Exceptions: ThreadStateException if the thread is dead.
=========================================================================*/
public bool IsBackground {
get { return IsBackgroundNative(); }
[HostProtection(SelfAffectingThreading=true)]
set { SetBackgroundNative(value); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsBackgroundNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetBackgroundNative(bool isBackground);
/*=========================================================================
** Return the thread state as a consistent set of bits. This is more
** general then IsAlive or IsBackground.
=========================================================================*/
public ThreadState ThreadState {
get { return (ThreadState)GetThreadStateNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetThreadStateNative();
#if FEATURE_COMINTEROP
/*=========================================================================
** An unstarted thread can be marked to indicate that it will host a
** single-threaded or multi-threaded apartment.
**
** Exceptions: ArgumentException if state is not a valid apartment state
** (ApartmentSTA or ApartmentMTA).
=========================================================================*/
[Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
public ApartmentState ApartmentState
{
get
{
return (ApartmentState)GetApartmentStateNative();
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
set
{
SetApartmentStateNative((int)value, true);
}
}
public ApartmentState GetApartmentState()
{
return (ApartmentState)GetApartmentStateNative();
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
public bool TrySetApartmentState(ApartmentState state)
{
return SetApartmentStateHelper(state, false);
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
public void SetApartmentState(ApartmentState state)
{
bool result = SetApartmentStateHelper(state, true);
if (!result)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed"));
}
private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
{
ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
// Special case where we pass in Unknown and get back MTA.
// Once we CoUninitialize the thread, the OS will still
// report the thread as implicitly in the MTA if any
// other thread in the process is CoInitialized.
if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
return true;
if (retState != state)
return false;
return true;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetApartmentStateNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int StartupSetApartmentStateInternal();
#endif // FEATURE_COMINTEROP
/*==========================================================================
** Allocates an un-named data slot. The slot is allocated on ALL the
** threads.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateDataSlot()
{
return LocalDataStoreManager.AllocateDataSlot();
}
/*=========================================================================
** Allocates a named data slot. The slot is allocated on ALL the
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
return LocalDataStoreManager.AllocateNamedDataSlot(name);
}
/*==========================================================================
** Looks up a named data slot. If the name has not been used, a new slot is
** allocated. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot GetNamedDataSlot(String name)
{
return LocalDataStoreManager.GetNamedDataSlot(name);
}
/*==========================================================================
** Frees a named data slot. The slot is allocated on ALL the
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static void FreeNamedDataSlot(String name)
{
LocalDataStoreManager.FreeNamedDataSlot(name);
}
/*=========================================================================
** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static Object GetData(LocalDataStoreSlot slot)
{
LocalDataStoreManager.ValidateSlot(slot);
LocalDataStore dls = GetDomainLocalStore();
if (dls == null)
return null;
return dls.GetData(slot);
}
/*==========================================================================
** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static void SetData(LocalDataStoreSlot slot, Object data)
{
LocalDataStore dls = GetDomainLocalStore();
// Create new DLS if one hasn't been created for this domain for this thread
if (dls == null) {
dls = LocalDataStoreManager.CreateLocalDataStore();
SetDomainLocalStore(dls);
}
dls.SetData(slot, data);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ResourceExposure(ResourceScope.AppDomain)]
static extern private LocalDataStore GetDomainLocalStore();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ResourceExposure(ResourceScope.AppDomain)]
static extern private void SetDomainLocalStore(LocalDataStore dls);
/***
* An appdomain has been unloaded - remove its DLS from the manager
*/
static private void RemoveDomainLocalStore(LocalDataStore dls)
{
if (dls != null)
LocalDataStoreManager.DeleteLocalDataStore(dls);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
// As the culture can be customized object then we cannot hold any
// reference to it before we check if it is safe because the app domain
// owning this customized culture may get unloaded while executing this
// code. To achieve that we have to do the check using nativeGetSafeCulture
// as the thread cannot get interrupted during the FCALL.
// If the culture is safe (not customized or created in current app domain)
// then the FCALL will return a reference to that culture otherwise the
// FCALL will return failure. In case of failure we'll return the default culture.
// If the app domain owning a customized culture that is set to teh thread and this
// 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 {
// Fetch a local copy of m_CurrentUICulture to
// avoid ----s that malicious user can introduce
if (m_CurrentUICulture == null) {
return CultureInfo.UserDefaultUICulture;
}
CultureInfo culture = null;
if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) {
return CultureInfo.UserDefaultUICulture;
}
return culture;
}
[HostProtection(ExternalThreading=true)]
set {
if (value == null) {
throw new ArgumentNullException("value");
}
//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);
if (nativeSetThreadUILocale(value.LCID) == false)
{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name));
}
value.StartCrossDomainTracking();
m_CurrentUICulture = value;
}
}
// This returns the exposed context for a given context ID.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeSetThreadUILocale(int LCID);
// As the culture can be customized object then we cannot hold any
// reference to it before we check if it is safe because the app domain
// owning this customized culture may get unloaded while executing this
// code. To achieve that we have to do the check using nativeGetSafeCulture
// as the thread cannot get interrupted during the FCALL.
// If the culture is safe (not customized or created in current app domain)
// then the FCALL will return a reference to that culture otherwise the
// FCALL will return failure. In case of failure we'll return the default culture.
// If the app domain owning a customized culture that is set to teh thread and this
// 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 {
// Fetch a local copy of m_CurrentCulture to
// avoid ----s that malicious user can introduce
if (m_CurrentCulture == null) {
return CultureInfo.UserDefaultCulture;
}
CultureInfo culture = null;
if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) {
return CultureInfo.UserDefaultCulture;
}
return culture;
}
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
set {
if (null==value) {
throw new ArgumentNullException("value");
}
CultureInfo.CheckNeutral(value);
//If we can't set the nativeThreadLocale, we'll just let it stay
//at whatever value it had before. This allows people who use
//just managed code not to be limited by the underlying OS.
CultureInfo.nativeSetThreadLocale(value.LCID);
value.StartCrossDomainTracking();
m_CurrentCulture = value;
}
}
/*===============================================================
====================== Thread Statics ===========================
===============================================================*/
private int ReserveSlot()
{
// This is called by the thread on itself so no need for locks
if (m_ThreadStaticsBuckets == null)
{
BCLDebug.Assert(STATICS_BUCKET_SIZE % 32 == 0,"STATICS_BUCKET_SIZE should be a multiple of 32");
// allocate bucket holder
// do not publish the data until all the intialization is done, in case of asynchronized exceptions
Object[][] newBuckets = new Object[1][];
SetIsThreadStaticsArray(newBuckets);
// allocate the first bucket
newBuckets[0] = new Object[STATICS_BUCKET_SIZE];
SetIsThreadStaticsArray(newBuckets[0]);
int[] newBits = new int[newBuckets.Length*STATICS_BUCKET_SIZE/32];
// use memset!
for (int i=0; i all slots occupied
if (slot == 0)
{
// We need to expand. Allocate a new bucket
int oldLength = m_ThreadStaticsBuckets.Length;
int oldLengthBits = m_ThreadStaticsBits.Length;
int newLength = m_ThreadStaticsBuckets.Length + 1;
Object[][] newBuckets = new Object[newLength][];
SetIsThreadStaticsArray(newBuckets);
int newLengthBits = newLength*STATICS_BUCKET_SIZE/32;
int[] newBits = new int[newLengthBits];
// Copy old buckets into new holder
Array.Copy(m_ThreadStaticsBuckets, newBuckets, m_ThreadStaticsBuckets.Length);
// Allocate new buckets
for (int i = oldLength ; i < newLength ; i++)
{
newBuckets[i] = new Object[STATICS_BUCKET_SIZE];
SetIsThreadStaticsArray(newBuckets[i]);
}
// Copy old bits into new bit array
Array.Copy(m_ThreadStaticsBits, newBits, m_ThreadStaticsBits.Length);
// Initalize new bits
for(int i= oldLengthBits ; i>16)&0xffff;
slot+=16;
}
if ((bits & 0xff) != 0)
{
bits = bits & 0xff;
}
else
{
slot+=8;
bits = (bits>>8)&0xff;
}
int j;
for (j=0; j<8; j++)
{
if ( (bits & (1< CancellationSignals {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get {
if (m_CancellationSignals == null) {
List signals = new List();
Interlocked.CompareExchange(ref m_CancellationSignals, signals, null);
}
return m_CancellationSignals;
}
}
#endif
/*==========================================================================
** Volatile Read & Write and MemoryBarrier methods.
** Provides the ability to read and write values ensuring that the values
** are read/written each time they are accessed.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static byte VolatileRead(ref byte address)
{
byte ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static short VolatileRead(ref short address)
{
short ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static int VolatileRead(ref int address)
{
int ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static long VolatileRead(ref long address)
{
long ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static sbyte VolatileRead(ref sbyte address)
{
sbyte ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static ushort VolatileRead(ref ushort address)
{
ushort ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static uint VolatileRead(ref uint address)
{
uint ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static IntPtr VolatileRead(ref IntPtr address)
{
IntPtr ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static UIntPtr VolatileRead(ref UIntPtr address)
{
UIntPtr ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static ulong VolatileRead(ref ulong address)
{
ulong ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static float VolatileRead(ref float address)
{
float ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static double VolatileRead(ref double address)
{
double ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static Object VolatileRead(ref Object address)
{
Object ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref byte address, byte value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref short address, short value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref int address, int value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref long address, long value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref sbyte address, sbyte value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref ushort address, ushort value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref uint address, uint value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref IntPtr address, IntPtr value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref UIntPtr address, UIntPtr value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref ulong address, ulong value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref float address, float value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref double address, double value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref Object address, Object value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void MemoryBarrier();
//We need to mark thread statics array for AppDomain leak checking purpose
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SetIsThreadStaticsArray(Object o);
private static LocalDataStoreMgr LocalDataStoreManager
{
get
{
if (s_LocalDataStoreMgr == null)
{
lock(s_SyncObject)
{
if (s_LocalDataStoreMgr == null)
s_LocalDataStoreMgr = new LocalDataStoreMgr();
}
}
return s_LocalDataStoreMgr;
}
}
void _Thread.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
// Helper function to set the AbortReason for a thread abort.
// Checks that they're not alredy set, and then atomically updates
// the reason info (object + ADID).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetAbortReason(Object o);
// Helper function to retrieve the AbortReason from a thread
// abort. Will perform cross-AppDomain marshalling if the object
// lives in a different AppDomain from the requester.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Object GetAbortReason();
// Helper function to clear the AbortReason. Takes care of
// AppDomain related cleanup if required.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void ClearAbortReason();
} // 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
// stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
// Declaring these in EH clauses is illegal; they must declared in the main method body
[Serializable]
internal enum StackCrawlMark
{
LookForMe = 0,
LookForMyCaller = 1,
LookForMyCallersCaller = 2,
LookForThread = 3
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*==============================================================================
**
** Class: Thread
**
**
** Purpose: Class for creating and managing a thread.
**
**
=============================================================================*/
namespace System.Threading {
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Messaging;
using System;
using System.Diagnostics;
using System.Security.Permissions;
using System.Security.Principal;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.Runtime.Versioning;
internal delegate Object InternalCrossContextDelegate(Object[] args);
internal class ThreadHelper
{
Delegate _start;
Object _startArg = null;
ExecutionContext _executionContext = null;
internal ThreadHelper(Delegate start)
{
_start = start;
}
internal void SetExecutionContextHelper(ExecutionContext ec)
{
_executionContext = ec;
}
static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
static internal void ThreadStart_Context(Object state)
{
ThreadHelper t = (ThreadHelper)state;
if (t._start is ThreadStart)
{
((ThreadStart)t._start)();
}
else
{
((ParameterizedThreadStart)t._start)(t._startArg);
}
}
// call back helper
internal void ThreadStart(object obj)
{
_startArg = obj;
if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
else
{
((ParameterizedThreadStart)_start)(obj);
}
}
// call back helper
internal void ThreadStart()
{
if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
else
{
((ThreadStart)_start)();
}
}
};
// deliberately not [serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Thread))]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Thread : CriticalFinalizerObject, _Thread
{
/*=========================================================================
** Data accessed from managed code that needs to be defined in
** ThreadBaseObject to maintain alignment between the two classes.
** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h
=========================================================================*/
private Context m_Context;
private ExecutionContext m_ExecutionContext; // this call context follows the logical thread
private String m_Name;
private Delegate m_Delegate; // Delegate
private Object[][] m_ThreadStaticsBuckets; // Holder for thread statics
private int[] m_ThreadStaticsBits; // Bit-markers for slot availability
private CultureInfo m_CurrentCulture;
private CultureInfo m_CurrentUICulture;
#if IO_CANCELLATION_ENABLED
internal List m_CancellationSignals; // IO Cancellation stack
#endif
private Object m_ThreadStartArg;
/*=========================================================================
** The base implementation of Thread is all native. The following fields
** should never be used in the C# code. They are here to define the proper
** space so the thread object may be allocated. DON'T CHANGE THESE UNLESS
** YOU MODIFY ThreadBaseObject in vm\object.h
=========================================================================*/
#pragma warning disable 169
#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
#pragma warning restore 414
#pragma warning restore 169
/*=========================================================================
** This manager is responsible for storing the global data that is
** shared amongst all the thread local stores.
=========================================================================*/
static private LocalDataStoreMgr s_LocalDataStoreMgr = null;
static private Object s_SyncObject = new Object();
// Has to be in [....] with THREAD_STATICS_BUCKET_SIZE in vm/threads.cpp
private const int STATICS_BUCKET_SIZE = 32;
/*==========================================================================
** Creates a new Thread object which will begin execution at
** start.ThreadStart on a new thread when the Start method is called.
**
** Exceptions: ArgumentNullException if start == null.
=========================================================================*/
public Thread(ThreadStart start) {
if (start == null) {
throw new ArgumentNullException("start");
}
SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize
}
public Thread(ThreadStart start, int maxStackSize) {
if (start == null) {
throw new ArgumentNullException("start");
}
if (0 > maxStackSize)
throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
SetStartHelper((Delegate)start, maxStackSize);
}
public Thread(ParameterizedThreadStart start) {
if (start == null) {
throw new ArgumentNullException("start");
}
SetStartHelper((Delegate)start, 0);
}
public Thread(ParameterizedThreadStart start, int maxStackSize) {
if (start == null) {
throw new ArgumentNullException("start");
}
if (0 > maxStackSize)
throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
SetStartHelper((Delegate)start, maxStackSize);
}
[ComVisible(false),
MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override int GetHashCode();
public int ManagedThreadId
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
return m_ManagedThreadId;
}
}
/*=========================================================================
** Spawns off a new thread which will begin executing at the ThreadStart
** method on the IThreadable interface passed in the constructor. Once the
** thread is dead, it cannot be restarted with another call to Start.
**
** Exceptions: ThreadStateException if the thread has already been started.
=========================================================================*/
[HostProtection(Synchronization=true,ExternalThreading=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Start()
{
#if FEATURE_COMINTEROP
// Eagerly initialize the COM Apartment state of the thread if we're allowed to.
StartupSetApartmentStateInternal();
#endif // FEATURE_COMINTEROP
// Attach current thread's security principal object to the new
// thread. Be careful not to bind the current thread to a principal
// if it's not already bound.
if (m_Delegate != null)
{
// If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of
// reporting an error. Just make sure we dont try to dereference a null delegate.
ThreadHelper t = (ThreadHelper)(m_Delegate.Target);
ExecutionContext ec = ExecutionContext.Capture();
ExecutionContext.ClearSyncContext(ec);
t.SetExecutionContextHelper(ec);
}
IPrincipal principal = (IPrincipal) CallContext.Principal;
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
StartInternal(principal, ref stackMark);
}
[HostProtection(Synchronization=true,ExternalThreading=true)]
public 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)
{
//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"));
}
m_ThreadStartArg = parameter;
Start();
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal ExecutionContext GetExecutionContextNoCreate()
{
return m_ExecutionContext;
}
public ExecutionContext ExecutionContext
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get
{
if (m_ExecutionContext == null && this == Thread.CurrentThread)
{
m_ExecutionContext = new ExecutionContext();
m_ExecutionContext.Thread = this;
}
return m_ExecutionContext;
}
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal void SetExecutionContext(ExecutionContext value) {
m_ExecutionContext = value;
if (value != null)
m_ExecutionContext.Thread = this;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark);
///
[StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"),
SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode),
DynamicSecurityMethodAttribute()]
[Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public void SetCompressedStack( CompressedStack stack )
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
}
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle);
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern void RestoreAppDomainStack( IntPtr appDomainStack);
///
[StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000"),
SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
[Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public CompressedStack GetCompressedStack()
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
}
// Helper method to get a logical thread ID for StringBuilder (for
// correctness) and for FileStream's async code path (for perf, to
// avoid creating a Thread instance).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static IntPtr InternalGetCurrentThread();
#if IO_CANCELLATION_ENABLED
// Internal method to get the OS thread handle for this thread.
internal extern IntPtr Handle {
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
#endif
/*==========================================================================
** Raises a ThreadAbortException in the thread, which usually
** results in the thread's death. The ThreadAbortException is a special
** exception that is not catchable. The finally clauses of all try
** statements will be executed before the thread dies. This includes the
** finally that a thread might be executing at the moment the Abort is raised.
** The thread is not stopped immediately--you must Join on the
** thread to guarantee it has stopped.
** It is possible for a thread to do an unbounded amount of computation in
** the finally's and thus indefinitely delay the threads death.
** If Abort() is called on a thread that has not been started, the thread
** will abort when Start() is called.
** If Abort is called twice on the same thread, a DuplicateThreadAbort
** exception is thrown.
=========================================================================*/
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public void Abort(Object stateInfo)
{
// If two aborts come at the same time, it is possible that the state info
// gets set by one, and the actual abort gets delivered by another. But this
// is not distinguishable by an application.
// The accessor helper will only set the value if it isn't already set,
// and that particular bit of native code can test much faster than this
// code could, because testing might cause a cross-appdomain marshalling.
AbortReason = stateInfo;
// Note: we demand ControlThread permission, then call AbortInternal directly
// rather than delegating to the Abort() function below. We do this to ensure
// that only callers with ControlThread are allowed to change the AbortReason
// of the thread. We call AbortInternal directly to avoid demanding the same
// permission twice.
AbortInternal();
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public void Abort() { AbortInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();
/*==========================================================================
** Resets a thread abort.
** Should be called by trusted code only
=========================================================================*/
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
public static void ResetAbort()
{
Thread thread = Thread.CurrentThread;
if ((thread.ThreadState & ThreadState.AbortRequested) == 0)
throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested"));
thread.ResetAbortNative();
thread.ClearAbortReason();
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void ResetAbortNative();
/*=========================================================================
** Suspends the thread. If the thread is already suspended, this call has
** no effect.
**
** Exceptions: ThreadStateException if the thread has not been started or
** it is dead.
=========================================================================*/
[Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)]
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Suspend() { SuspendInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SuspendInternal();
/*==========================================================================
** Resumes a thread that has been suspended.
**
** Exceptions: ThreadStateException if the thread has not been started or
** it is dead or it isn't in the suspended state.
=========================================================================*/
[Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)]
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Resume() { ResumeInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void ResumeInternal();
/*=========================================================================
** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that
** thread is not currently blocked in that manner, it will be interrupted
** when it next begins to block.
=========================================================================*/
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
public void Interrupt() { InterruptInternal(); }
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InterruptInternal();
/*=========================================================================
** Returns the priority of the thread.
**
** Exceptions: ThreadStateException if the thread is dead.
=========================================================================*/
public ThreadPriority Priority {
get { return (ThreadPriority)GetPriorityNative(); }
[HostProtection(SelfAffectingThreading=true)]
set { SetPriorityNative((int)value); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetPriorityNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetPriorityNative(int priority);
/*=========================================================================
** Returns true if the thread has been started and is not dead.
=========================================================================*/
public bool IsAlive {
get { return IsAliveNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsAliveNative();
/*==========================================================================
** Returns true if the thread is a threadpool thread.
=========================================================================*/
public bool IsThreadPoolThread {
get { return IsThreadpoolThreadNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsThreadpoolThreadNative();
/*=========================================================================
** Waits for the thread to die.
**
** Exceptions: ThreadInterruptedException if the thread is interrupted while waiting.
** ThreadStateException if the thread has not been started yet.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[HostProtection(Synchronization=true, ExternalThreading=true)]
private extern void JoinInternal();
[HostProtection(Synchronization=true, ExternalThreading=true)]
public void Join()
{
JoinInternal();
}
/*==========================================================================
** Waits for the thread to die or for timeout milliseconds to elapse.
** Returns true if the thread died, or false if the wait timed out. If
** Timeout.Infinite is given as the parameter, no timeout will occur.
**
** Exceptions: ArgumentException if timeout < 0.
** ThreadInterruptedException if the thread is interrupted while waiting.
** ThreadStateException if the thread has not been started yet.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[HostProtection(Synchronization=true, ExternalThreading=true)]
private extern bool JoinInternal(int millisecondsTimeout);
[HostProtection(Synchronization=true, ExternalThreading=true)]
public bool Join(int millisecondsTimeout)
{
return JoinInternal(millisecondsTimeout);
}
[HostProtection(Synchronization=true, ExternalThreading=true)]
public bool Join(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return Join((int)tm);
}
/*==========================================================================
** Suspends the current thread for timeout milliseconds. If timeout == 0,
** forces the thread to give up the remainer of its timeslice. If timeout
** == Timeout.Infinite, no timeout will occur.
**
** Exceptions: ArgumentException if timeout < 0.
** ThreadInterruptedException if the thread is interrupted while sleeping.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);
public static void Sleep(int millisecondsTimeout)
{
SleepInternal(millisecondsTimeout);
}
public static void Sleep(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Sleep((int)tm);
}
/* wait for a length of time proportial to 'iterations'. Each iteration is should
only take a few machine instructions. Calling this API is preferable to coding
a explict busy loop because the hardware can be informed that it is busy waiting. */
[MethodImplAttribute(MethodImplOptions.InternalCall),
HostProtection(Synchronization=true,ExternalThreading=true),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern void SpinWaitInternal(int iterations);
[HostProtection(Synchronization=true,ExternalThreading=true),
ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void SpinWait(int iterations)
{
SpinWaitInternal(iterations);
}
public static Thread CurrentThread {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get {
Thread th;
th = GetFastCurrentThreadNative();
if (th == null)
th = GetCurrentThreadNative();
return th;
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern Thread GetCurrentThreadNative();
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern Thread GetFastCurrentThreadNative();
private void SetStartHelper(Delegate start, int maxStackSize)
{
ThreadHelper threadStartCallBack = new ThreadHelper(start);
if(start is ThreadStart)
{
SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
}
else
{
SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
}
}
/*=========================================================================
** PRIVATE Sets the IThreadable interface for the thread. Assumes that
** start != null.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetStart(Delegate start, int maxStackSize);
/*==========================================================================
** Clean up the thread when it goes away.
=========================================================================*/
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~Thread()
{
// Delegate to the unmanaged portion.
InternalFinalize();
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InternalFinalize();
/*=========================================================================
** Return whether or not this thread is a background thread. Background
** threads do not affect when the Execution Engine shuts down.
**
** Exceptions: ThreadStateException if the thread is dead.
=========================================================================*/
public bool IsBackground {
get { return IsBackgroundNative(); }
[HostProtection(SelfAffectingThreading=true)]
set { SetBackgroundNative(value); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsBackgroundNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetBackgroundNative(bool isBackground);
/*=========================================================================
** Return the thread state as a consistent set of bits. This is more
** general then IsAlive or IsBackground.
=========================================================================*/
public ThreadState ThreadState {
get { return (ThreadState)GetThreadStateNative(); }
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetThreadStateNative();
#if FEATURE_COMINTEROP
/*=========================================================================
** An unstarted thread can be marked to indicate that it will host a
** single-threaded or multi-threaded apartment.
**
** Exceptions: ArgumentException if state is not a valid apartment state
** (ApartmentSTA or ApartmentMTA).
=========================================================================*/
[Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
public ApartmentState ApartmentState
{
get
{
return (ApartmentState)GetApartmentStateNative();
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
set
{
SetApartmentStateNative((int)value, true);
}
}
public ApartmentState GetApartmentState()
{
return (ApartmentState)GetApartmentStateNative();
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
public bool TrySetApartmentState(ApartmentState state)
{
return SetApartmentStateHelper(state, false);
}
[HostProtection(Synchronization=true, SelfAffectingThreading=true)]
public void SetApartmentState(ApartmentState state)
{
bool result = SetApartmentStateHelper(state, true);
if (!result)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed"));
}
private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
{
ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
// Special case where we pass in Unknown and get back MTA.
// Once we CoUninitialize the thread, the OS will still
// report the thread as implicitly in the MTA if any
// other thread in the process is CoInitialized.
if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
return true;
if (retState != state)
return false;
return true;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int GetApartmentStateNative();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int StartupSetApartmentStateInternal();
#endif // FEATURE_COMINTEROP
/*==========================================================================
** Allocates an un-named data slot. The slot is allocated on ALL the
** threads.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateDataSlot()
{
return LocalDataStoreManager.AllocateDataSlot();
}
/*=========================================================================
** Allocates a named data slot. The slot is allocated on ALL the
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
return LocalDataStoreManager.AllocateNamedDataSlot(name);
}
/*==========================================================================
** Looks up a named data slot. If the name has not been used, a new slot is
** allocated. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot GetNamedDataSlot(String name)
{
return LocalDataStoreManager.GetNamedDataSlot(name);
}
/*==========================================================================
** Frees a named data slot. The slot is allocated on ALL the
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
public static void FreeNamedDataSlot(String name)
{
LocalDataStoreManager.FreeNamedDataSlot(name);
}
/*=========================================================================
** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static Object GetData(LocalDataStoreSlot slot)
{
LocalDataStoreManager.ValidateSlot(slot);
LocalDataStore dls = GetDomainLocalStore();
if (dls == null)
return null;
return dls.GetData(slot);
}
/*==========================================================================
** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
=========================================================================*/
[HostProtection(SharedState=true, ExternalThreading=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static void SetData(LocalDataStoreSlot slot, Object data)
{
LocalDataStore dls = GetDomainLocalStore();
// Create new DLS if one hasn't been created for this domain for this thread
if (dls == null) {
dls = LocalDataStoreManager.CreateLocalDataStore();
SetDomainLocalStore(dls);
}
dls.SetData(slot, data);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ResourceExposure(ResourceScope.AppDomain)]
static extern private LocalDataStore GetDomainLocalStore();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ResourceExposure(ResourceScope.AppDomain)]
static extern private void SetDomainLocalStore(LocalDataStore dls);
/***
* An appdomain has been unloaded - remove its DLS from the manager
*/
static private void RemoveDomainLocalStore(LocalDataStore dls)
{
if (dls != null)
LocalDataStoreManager.DeleteLocalDataStore(dls);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
// As the culture can be customized object then we cannot hold any
// reference to it before we check if it is safe because the app domain
// owning this customized culture may get unloaded while executing this
// code. To achieve that we have to do the check using nativeGetSafeCulture
// as the thread cannot get interrupted during the FCALL.
// If the culture is safe (not customized or created in current app domain)
// then the FCALL will return a reference to that culture otherwise the
// FCALL will return failure. In case of failure we'll return the default culture.
// If the app domain owning a customized culture that is set to teh thread and this
// 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 {
// Fetch a local copy of m_CurrentUICulture to
// avoid ----s that malicious user can introduce
if (m_CurrentUICulture == null) {
return CultureInfo.UserDefaultUICulture;
}
CultureInfo culture = null;
if (!nativeGetSafeCulture(this, GetDomainID(), true, ref culture) || culture == null) {
return CultureInfo.UserDefaultUICulture;
}
return culture;
}
[HostProtection(ExternalThreading=true)]
set {
if (value == null) {
throw new ArgumentNullException("value");
}
//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);
if (nativeSetThreadUILocale(value.LCID) == false)
{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", value.Name));
}
value.StartCrossDomainTracking();
m_CurrentUICulture = value;
}
}
// This returns the exposed context for a given context ID.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeSetThreadUILocale(int LCID);
// As the culture can be customized object then we cannot hold any
// reference to it before we check if it is safe because the app domain
// owning this customized culture may get unloaded while executing this
// code. To achieve that we have to do the check using nativeGetSafeCulture
// as the thread cannot get interrupted during the FCALL.
// If the culture is safe (not customized or created in current app domain)
// then the FCALL will return a reference to that culture otherwise the
// FCALL will return failure. In case of failure we'll return the default culture.
// If the app domain owning a customized culture that is set to teh thread and this
// 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 {
// Fetch a local copy of m_CurrentCulture to
// avoid ----s that malicious user can introduce
if (m_CurrentCulture == null) {
return CultureInfo.UserDefaultCulture;
}
CultureInfo culture = null;
if (!nativeGetSafeCulture(this, GetDomainID(), false, ref culture) || culture == null) {
return CultureInfo.UserDefaultCulture;
}
return culture;
}
[SecurityPermission(SecurityAction.Demand, ControlThread=true)]
set {
if (null==value) {
throw new ArgumentNullException("value");
}
CultureInfo.CheckNeutral(value);
//If we can't set the nativeThreadLocale, we'll just let it stay
//at whatever value it had before. This allows people who use
//just managed code not to be limited by the underlying OS.
CultureInfo.nativeSetThreadLocale(value.LCID);
value.StartCrossDomainTracking();
m_CurrentCulture = value;
}
}
/*===============================================================
====================== Thread Statics ===========================
===============================================================*/
private int ReserveSlot()
{
// This is called by the thread on itself so no need for locks
if (m_ThreadStaticsBuckets == null)
{
BCLDebug.Assert(STATICS_BUCKET_SIZE % 32 == 0,"STATICS_BUCKET_SIZE should be a multiple of 32");
// allocate bucket holder
// do not publish the data until all the intialization is done, in case of asynchronized exceptions
Object[][] newBuckets = new Object[1][];
SetIsThreadStaticsArray(newBuckets);
// allocate the first bucket
newBuckets[0] = new Object[STATICS_BUCKET_SIZE];
SetIsThreadStaticsArray(newBuckets[0]);
int[] newBits = new int[newBuckets.Length*STATICS_BUCKET_SIZE/32];
// use memset!
for (int i=0; i all slots occupied
if (slot == 0)
{
// We need to expand. Allocate a new bucket
int oldLength = m_ThreadStaticsBuckets.Length;
int oldLengthBits = m_ThreadStaticsBits.Length;
int newLength = m_ThreadStaticsBuckets.Length + 1;
Object[][] newBuckets = new Object[newLength][];
SetIsThreadStaticsArray(newBuckets);
int newLengthBits = newLength*STATICS_BUCKET_SIZE/32;
int[] newBits = new int[newLengthBits];
// Copy old buckets into new holder
Array.Copy(m_ThreadStaticsBuckets, newBuckets, m_ThreadStaticsBuckets.Length);
// Allocate new buckets
for (int i = oldLength ; i < newLength ; i++)
{
newBuckets[i] = new Object[STATICS_BUCKET_SIZE];
SetIsThreadStaticsArray(newBuckets[i]);
}
// Copy old bits into new bit array
Array.Copy(m_ThreadStaticsBits, newBits, m_ThreadStaticsBits.Length);
// Initalize new bits
for(int i= oldLengthBits ; i>16)&0xffff;
slot+=16;
}
if ((bits & 0xff) != 0)
{
bits = bits & 0xff;
}
else
{
slot+=8;
bits = (bits>>8)&0xff;
}
int j;
for (j=0; j<8; j++)
{
if ( (bits & (1< CancellationSignals {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get {
if (m_CancellationSignals == null) {
List signals = new List();
Interlocked.CompareExchange(ref m_CancellationSignals, signals, null);
}
return m_CancellationSignals;
}
}
#endif
/*==========================================================================
** Volatile Read & Write and MemoryBarrier methods.
** Provides the ability to read and write values ensuring that the values
** are read/written each time they are accessed.
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static byte VolatileRead(ref byte address)
{
byte ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static short VolatileRead(ref short address)
{
short ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static int VolatileRead(ref int address)
{
int ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static long VolatileRead(ref long address)
{
long ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static sbyte VolatileRead(ref sbyte address)
{
sbyte ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static ushort VolatileRead(ref ushort address)
{
ushort ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static uint VolatileRead(ref uint address)
{
uint ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static IntPtr VolatileRead(ref IntPtr address)
{
IntPtr ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static UIntPtr VolatileRead(ref UIntPtr address)
{
UIntPtr ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static ulong VolatileRead(ref ulong address)
{
ulong ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static float VolatileRead(ref float address)
{
float ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static double VolatileRead(ref double address)
{
double ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static Object VolatileRead(ref Object address)
{
Object ret = address;
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref byte address, byte value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref short address, short value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref int address, int value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref long address, long value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref sbyte address, sbyte value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref ushort address, ushort value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref uint address, uint value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref IntPtr address, IntPtr value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref UIntPtr address, UIntPtr value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref ulong address, ulong value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref float address, float value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref double address, double value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations
public static void VolatileWrite(ref Object address, Object value)
{
MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
address = value;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void MemoryBarrier();
//We need to mark thread statics array for AppDomain leak checking purpose
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SetIsThreadStaticsArray(Object o);
private static LocalDataStoreMgr LocalDataStoreManager
{
get
{
if (s_LocalDataStoreMgr == null)
{
lock(s_SyncObject)
{
if (s_LocalDataStoreMgr == null)
s_LocalDataStoreMgr = new LocalDataStoreMgr();
}
}
return s_LocalDataStoreMgr;
}
}
void _Thread.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
// Helper function to set the AbortReason for a thread abort.
// Checks that they're not alredy set, and then atomically updates
// the reason info (object + ADID).
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetAbortReason(Object o);
// Helper function to retrieve the AbortReason from a thread
// abort. Will perform cross-AppDomain marshalling if the object
// lives in a different AppDomain from the requester.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Object GetAbortReason();
// Helper function to clear the AbortReason. Takes care of
// AppDomain related cleanup if required.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void ClearAbortReason();
} // 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
// stack crawl will both prevent inlining of the calle and pass an ESP point to stack crawl to
// Declaring these in EH clauses is illegal; they must declared in the main method body
[Serializable]
internal enum StackCrawlMark
{
LookForMe = 0,
LookForMyCaller = 1,
LookForMyCallersCaller = 2,
LookForThread = 3
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SiteMapDataSourceView.cs
- RectAnimation.cs
- NavigationPropertyEmitter.cs
- ReversePositionQuery.cs
- DesignerView.cs
- PrivilegedConfigurationManager.cs
- DesignColumnCollection.cs
- FileRecordSequenceCompletedAsyncResult.cs
- NativeMethodsCLR.cs
- PkcsUtils.cs
- OrderedDictionaryStateHelper.cs
- ISAPIWorkerRequest.cs
- SchemaElement.cs
- SerializationTrace.cs
- ComAdminInterfaces.cs
- SpellerInterop.cs
- CaseInsensitiveHashCodeProvider.cs
- TableItemProviderWrapper.cs
- CngProperty.cs
- CodeExpressionStatement.cs
- OleDbDataAdapter.cs
- WebScriptMetadataMessage.cs
- SmiTypedGetterSetter.cs
- PeerDuplexChannel.cs
- BaseWebProxyFinder.cs
- InfoCardBinaryReader.cs
- SamlSecurityToken.cs
- BinaryMessageFormatter.cs
- SimpleWorkerRequest.cs
- TextUtf8RawTextWriter.cs
- GraphicsPathIterator.cs
- FontFamily.cs
- ScalarOps.cs
- NamedObject.cs
- SecurityTokenValidationException.cs
- NetStream.cs
- ServicePointManager.cs
- HMACSHA1.cs
- ReferenceEqualityComparer.cs
- HttpChannelBindingToken.cs
- X509SecurityTokenAuthenticator.cs
- ParentUndoUnit.cs
- ColumnMapTranslator.cs
- InfoCardMasterKey.cs
- InternalConfigEventArgs.cs
- SolidColorBrush.cs
- OdbcUtils.cs
- NetTcpSection.cs
- XmlUtil.cs
- Vertex.cs
- InfoCardArgumentException.cs
- ZoneLinkButton.cs
- XPathNavigator.cs
- InstanceDescriptor.cs
- WindowsFormsHelpers.cs
- CodeConditionStatement.cs
- InvalidCastException.cs
- SqlFunctionAttribute.cs
- UmAlQuraCalendar.cs
- XmlObjectSerializerReadContext.cs
- BlobPersonalizationState.cs
- MonitoringDescriptionAttribute.cs
- AppDomain.cs
- LongValidatorAttribute.cs
- util.cs
- Utils.cs
- HtmlLabelAdapter.cs
- AlignmentYValidation.cs
- Listbox.cs
- CodeVariableReferenceExpression.cs
- GuidConverter.cs
- DataBoundControlAdapter.cs
- TrackBarRenderer.cs
- Vector.cs
- RadioButton.cs
- HtmlInputText.cs
- MemberHolder.cs
- SectionInformation.cs
- Empty.cs
- FunctionImportElement.cs
- storepermissionattribute.cs
- WsatTransactionInfo.cs
- PeerTransportBindingElement.cs
- ContainerParagraph.cs
- RecognizerBase.cs
- AuthorizationRule.cs
- WebPartManagerInternals.cs
- Rotation3D.cs
- TerminatorSinks.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- SubstitutionList.cs
- Parameter.cs
- glyphs.cs
- CurrentTimeZone.cs
- HtmlControl.cs
- TextEditorTyping.cs
- ListViewVirtualItemsSelectionRangeChangedEvent.cs
- TableItemPattern.cs
- Bits.cs
- Track.cs