This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / corlib / System.Threading / Thread.cs
index d05639d9bfc9926c8bcbcae1df71354a73680727..911fb1dbe12b580ff072932e739627e97064edf5 100755 (executable)
@@ -8,6 +8,29 @@
 // Copyright (C) 2004 Novell (http://www.novell.com)
 //
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System.Runtime.Remoting.Contexts;
 using System.Security.Permissions;
 using System.Security.Principal;
@@ -45,6 +68,9 @@ namespace System.Threading
                private IntPtr lock_data;
                private IntPtr appdomain_refs;
                private bool interruption_requested;
+               private IntPtr suspend_event;
+               private IntPtr resume_event;
+               private object synch_lock = new Object();
                #endregion
 
                private ThreadStart threadstart;
@@ -61,10 +87,13 @@ namespace System.Threading
                public static IPrincipal CurrentPrincipal {
                        get {
                                IPrincipal p = null;
-                               lock (typeof (Thread)) {
-                                       p = CurrentThread._principal;
-                                       if (p == null)
+                               Thread th = CurrentThread;
+                               lock (th) {
+                                       p = th._principal;
+                                       if (p == null) {
                                                p = GetDomain ().DefaultPrincipal;
+                                               th._principal = p;
+                                       }
                                }
                                return p;
                        }
@@ -128,9 +157,10 @@ namespace System.Threading
 
                // Stores a hash keyed by strings of LocalDataStoreSlot objects
                static Hashtable datastorehash;
-
+               private static object datastore_lock = new object ();
+               
                private static void InitDataStoreHash () {
-                       lock (typeof (Thread)) {
+                       lock (datastore_lock) {
                                if (datastorehash == null) {
                                        datastorehash = Hashtable.Synchronized(new Hashtable());
                                }
@@ -138,7 +168,7 @@ namespace System.Threading
                }
                
                public static LocalDataStoreSlot AllocateNamedDataSlot(string name) {
-                       lock (typeof (Thread)) {
+                       lock (datastore_lock) {
                                if (datastorehash == null)
                                        InitDataStoreHash ();
                                LocalDataStoreSlot slot = (LocalDataStoreSlot)datastorehash[name];
@@ -157,7 +187,7 @@ namespace System.Threading
                }
 
                public static void FreeNamedDataSlot(string name) {
-                       lock (typeof (Thread)) {
+                       lock (datastore_lock) {
                                if (datastorehash == null)
                                        InitDataStoreHash ();
                                LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
@@ -181,15 +211,17 @@ namespace System.Threading
                public extern static int GetDomainID();
 
                public static LocalDataStoreSlot GetNamedDataSlot(string name) {
-                       if (datastorehash == null)
-                               InitDataStoreHash ();
-                       LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
+                       lock (datastore_lock) {
+                               if (datastorehash == null)
+                                       InitDataStoreHash ();
+                               LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
 
-                       if(slot==null) {
-                               slot=AllocateNamedDataSlot(name);
-                       }
+                               if(slot==null) {
+                                       slot=AllocateNamedDataSlot(name);
+                               }
                        
-                       return(slot);
+                               return(slot);
+                       }
                }
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -220,11 +252,7 @@ namespace System.Threading
                                throw new ArgumentException("Negative timeout");
                        }
                        Thread thread=CurrentThread;
-                               
-                       thread.set_state(ThreadState.WaitSleepJoin);
-                               
                        Sleep_internal(millisecondsTimeout);
-                       thread.clr_state(ThreadState.WaitSleepJoin);
                }
 
                public static void Sleep(TimeSpan timeout) {
@@ -236,10 +264,7 @@ namespace System.Threading
                        }
 
                        Thread thread=CurrentThread;
-                               
-                       thread.set_state(ThreadState.WaitSleepJoin);
                        Sleep_internal(ms);
-                       thread.clr_state(ThreadState.WaitSleepJoin);
                }
 
                // Returns the system thread handle
@@ -256,7 +281,6 @@ namespace System.Threading
                [MonoTODO]
                public ApartmentState ApartmentState {
                        get {
-                               // FIXME
                                return(ApartmentState.Unknown);
                        }
                        
@@ -305,7 +329,7 @@ namespace System.Threading
                public CultureInfo CurrentUICulture {
                        get {
                                if (current_ui_culture == null) {
-                                       lock (this) {
+                                       lock (synch_lock) {
                                                if(current_ui_culture==null) {
                                                        /* We don't
                                                         * distinguish
@@ -390,7 +414,7 @@ namespace System.Threading
                        }
                        
                        set {
-                               lock (this) {
+                               lock (synch_lock) {
                                        if(Name!=null) {
                                                throw new InvalidOperationException ("Thread.Name can only be set once.");
                                        }
@@ -403,7 +427,6 @@ namespace System.Threading
                [MonoTODO]
                public ThreadPriority Priority {
                        get {
-                               // FIXME
                                return(ThreadPriority.Lowest);
                        }
                        
@@ -431,7 +454,6 @@ namespace System.Threading
 
                [MonoTODO]
                public void Interrupt() {
-                       // FIXME
                }
 
                // The current thread joins with 'this'. Set ms to 0 to block
@@ -446,9 +468,7 @@ namespace System.Threading
                        
                        Thread thread=CurrentThread;
                                
-                       thread.set_state(ThreadState.WaitSleepJoin);
                        Join_internal(Timeout.Infinite, system_thread_handle);
-                       thread.clr_state(ThreadState.WaitSleepJoin);
                }
 
                public bool Join(int millisecondsTimeout) {
@@ -460,13 +480,7 @@ namespace System.Threading
                        }
 
                        Thread thread=CurrentThread;
-                               
-                       thread.set_state(ThreadState.WaitSleepJoin);
-                       bool ret=Join_internal(millisecondsTimeout,
-                                              system_thread_handle);
-                       thread.clr_state(ThreadState.WaitSleepJoin);
-
-                       return(ret);
+                       return Join_internal(millisecondsTimeout, system_thread_handle);
                }
 
                public bool Join(TimeSpan timeout) {
@@ -481,12 +495,7 @@ namespace System.Threading
                        }
 
                        Thread thread=CurrentThread;
-
-                       thread.set_state(ThreadState.WaitSleepJoin);
-                       bool ret=Join_internal(ms, system_thread_handle);
-                       thread.clr_state(ThreadState.WaitSleepJoin);
-
-                       return(ret);
+                       return Join_internal(ms, system_thread_handle);
                }
 
 #if NET_1_1
@@ -521,7 +530,7 @@ namespace System.Threading
                private extern void Start_internal(IntPtr handle);
                
                public void Start() {
-                       lock(this) {
+                       lock(synch_lock) {
                                if((state & ThreadState.Unstarted) == 0) {
                                        throw new ThreadStateException("Thread has already been started");
                                }
@@ -567,12 +576,12 @@ namespace System.Threading
                }
 
                private void set_state(ThreadState set) {
-                       lock(this) {
+                       lock(synch_lock) {
                                state |= set;
                        }
                }
                private void clr_state(ThreadState clr) {
-                       lock(this) {
+                       lock(synch_lock) {
                                state &= ~clr;
                        }
                }
@@ -621,7 +630,7 @@ namespace System.Threading
 
                [CLSCompliant (false)]
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern public static byte VolatileRead (ref UIntPtr address);
+               extern public static UIntPtr VolatileRead (ref UIntPtr address);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern public static void VolatileWrite (ref byte address, byte value);