#if NET_2_0
[ComVisible (true)]
[ComDefaultInterface (typeof (_Thread))]
-#endif
+ public sealed class Thread : CriticalFinalizerObject, _Thread {
+#else
public sealed class Thread : _Thread {
+#endif
#region Sync with metadata/object-internals.h
int lock_thread_id;
// stores a thread handle
private IntPtr system_thread_handle;
-
- private IntPtr culture_info;
- private IntPtr ui_culture_info;
+
+ /* Note this is an opaque object (an array), not a CultureInfo */
+ private object cached_culture_info;
+ private IntPtr unused0;
private bool threadpool_thread;
/* accessed only from unmanaged code */
private IntPtr name;
private object abort_exc;
internal object abort_state;
/* thread_id is only accessed from unmanaged code */
- private int thread_id;
+ private Int64 thread_id;
/* start_notify is used by the runtime to signal that Start()
* is ok to return
private IntPtr unused7;
#endregion
+ // the name of local_slots is important as it's used by the runtime.
[ThreadStatic]
- static Hashtable slothash;
+ static object[] local_slots;
// can be both a ThreadSart and a ParameterizedThreadStart
private MulticastDelegate threadstart;
internal static int CurrentThreadId {
get {
- return CurrentThread.thread_id;
+ return (int)(CurrentThread.thread_id);
}
}
}
}
- public static LocalDataStoreSlot AllocateNamedDataSlot(string name) {
+ public static LocalDataStoreSlot AllocateNamedDataSlot (string name) {
lock (datastore_lock) {
if (datastorehash == null)
InitDataStoreHash ();
- LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash[name];
- if(slot!=null) {
+ LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash [name];
+ if (slot != null) {
// This exception isnt documented (of
// course) but .net throws it
throw new ArgumentException("Named data slot already added");
}
- slot = new LocalDataStoreSlot();
+ slot = AllocateDataSlot ();
- datastorehash.Add(name, slot);
+ datastorehash.Add (name, slot);
- return(slot);
+ return slot;
}
}
- public static void FreeNamedDataSlot(string name) {
+ public static void FreeNamedDataSlot (string name) {
lock (datastore_lock) {
if (datastorehash == null)
InitDataStoreHash ();
- LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
+ LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash [name];
- if(slot!=null) {
- datastorehash.Remove(slot);
+ if (slot != null) {
+ datastorehash.Remove (slot);
}
}
}
- private static Hashtable SlotHash {
- get {
- if (slothash == null)
- slothash = new Hashtable ();
- return slothash;
- }
- }
-
- public static LocalDataStoreSlot AllocateDataSlot() {
- return new LocalDataStoreSlot();
+ public static LocalDataStoreSlot AllocateDataSlot () {
+ return new LocalDataStoreSlot (true);
}
- public static object GetData(LocalDataStoreSlot slot) {
- return SlotHash [slot];
+ public static object GetData (LocalDataStoreSlot slot) {
+ object[] slots = local_slots;
+ if (slot == null)
+ throw new ArgumentNullException ("slot");
+ if (slots != null && slot.slot < slots.Length)
+ return slots [slot.slot];
+ return null;
}
- public static void SetData(LocalDataStoreSlot slot,
- object data) {
- SlotHash [slot] = data;
+ public static void SetData (LocalDataStoreSlot slot, object data) {
+ object[] slots = local_slots;
+ if (slot == null)
+ throw new ArgumentNullException ("slot");
+ if (slots == null) {
+ slots = new object [slot.slot + 2];
+ local_slots = slots;
+ } else if (slot.slot >= slots.Length) {
+ object[] nslots = new object [slot.slot + 2];
+ slots.CopyTo (nslots, 0);
+ slots = nslots;
+ local_slots = slots;
+ }
+ slots [slot.slot] = data;
}
public static AppDomain GetDomain() {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static int GetDomainID();
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void FreeLocalSlotValues (int slot, bool thread_local);
+
public static LocalDataStoreSlot GetNamedDataSlot(string name) {
lock (datastore_lock) {
if (datastorehash == null)
[SecurityPermission (SecurityAction.Demand, ControlThread=true)]
public void Interrupt ()
{
+ throw new NotImplementedException ();
}
// The current thread joins with 'this'. Set ms to 0 to block
}
#if NET_1_1
- [MonoTODO ("seems required for multi-processors systems like Itanium")]
- public static void MemoryBarrier ()
- {
- // Will be implemented when we support Itanium
- }
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern static void MemoryBarrier ();
#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void Resume_internal();
if (SecurityManager.SecurityEnabled)
_ec = ExecutionContext.Capture ();
#endif
+ if (CurrentThread._principal != null)
+ _principal = CurrentThread._principal;
// Thread_internal creates and starts the new thread,
if (Thread_internal(threadstart) == (IntPtr) 0)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void Thread_free_internal(IntPtr handle);
+#if NET_2_0
+ [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
+#endif
~Thread() {
// Free up the handle
if (system_thread_handle != (IntPtr) 0)
public int ManagedThreadId {
[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- get { return thread_id; }
+ get { return (int)thread_id; }
}
[MonoTODO]
public override int GetHashCode ()
{
// ??? overridden but not guaranteed to be unique ???
- return thread_id;
+ return (int)thread_id;
}
public void Start (object parameter)
// But it's there!
[SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
[StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
+#if NET_2_0
+ [Obsolete ("see CompressedStack class")]
+#endif
#if NET_1_1
public
#else
// But it's there!
[SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
[StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
+#if NET_2_0
+ [Obsolete ("see CompressedStack class")]
+#endif
#if NET_1_1
public
#else