Преглед изворни кода

2001-09-25 Dick Porter <[email protected]>

	* Thread.cs: Implement Join and timed Join, set correct state
	around Start, Join and Sleep calls, implement IsAlive and
	ThreadState properties.

	* ThreadState.cs (Threading): Added StopRequested,
	SuspendRequested, Suspended values

svn path=/trunk/mcs/; revision=947
Dick Porter пре 24 година
родитељ
комит
91ee016e23

+ 9 - 0
mcs/class/corlib/System.Threading/ChangeLog

@@ -1,3 +1,12 @@
+2001-09-25  Dick Porter  <[email protected]>
+
+	* Thread.cs: Implement Join and timed Join, set correct state
+	around Start, Join and Sleep calls, implement IsAlive and
+	ThreadState properties.
+
+	* ThreadState.cs (Threading): Added StopRequested,
+	SuspendRequested, Suspended values
+
 2001-09-23  Dick Porter  <[email protected]>
 
 	* Thread.cs: Implemented CurrentThread and Sleep (both versions)

+ 77 - 18
mcs/class/corlib/System.Threading/Thread.cs

@@ -104,11 +104,18 @@ namespace System.Threading
 			if(millisecondsTimeout==0) {
 				// Schedule another thread
 				Schedule_internal();
+			} else {
+				Thread thread=CurrentThread;
+				
+				thread.state |= ThreadState.WaitSleepJoin;
+				int ms_remaining=Sleep_internal(millisecondsTimeout);
+				thread.state &= ~ThreadState.WaitSleepJoin;
+
+				if(ms_remaining>0) {
+					throw new ThreadInterruptedException("Thread interrupted while sleeping");
+				}
 			}
-			int ms_remaining=Sleep_internal(millisecondsTimeout);
-			if(ms_remaining>0) {
-				throw new ThreadInterruptedException("Thread interrupted while sleeping");
-			}
+			
 		}
 
 		public static void Sleep(TimeSpan timeout) {
@@ -119,10 +126,16 @@ namespace System.Threading
 			if(timeout.Milliseconds==0) {
 				// Schedule another thread
 				Schedule_internal();
-			}
-			int ms_remaining=Sleep_internal(timeout.Milliseconds);
-			if(ms_remaining>0) {
-				throw new ThreadInterruptedException("Thread interrupted while sleeping");
+			} else {
+				Thread thread=CurrentThread;
+				
+				thread.state |= ThreadState.WaitSleepJoin;
+				int ms_remaining=Sleep_internal(timeout.Milliseconds);
+				thread.state &= ~ThreadState.WaitSleepJoin;
+				
+				if(ms_remaining>0) {
+					throw new ThreadInterruptedException("Thread interrupted while sleeping");
+				}
 			}
 		}
 
@@ -172,8 +185,13 @@ namespace System.Threading
 
 		public bool IsAlive {
 			get {
-				// FIXME
-				return(false);
+				// LAMESPEC: is a Stopped thread dead?
+				if((state & ThreadState.Running) != 0 ||
+				   (state & ThreadState.Stopped) != 0) {
+					return(true);
+				} else {
+					return(false);
+				}
 			}
 		}
 
@@ -209,10 +227,11 @@ namespace System.Threading
 			}
 		}
 
+		private ThreadState state=ThreadState.Unstarted;
+		
 		public ThreadState ThreadState {
 			get {
-				// FIXME
-				return(ThreadState.Unstarted);
+				return(state);
 			}
 		}
 
@@ -228,16 +247,39 @@ namespace System.Threading
 			// FIXME
 		}
 
+		// The current thread joins with 'this'. Set ms to 0 to block
+		// until this actually exits.
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		private extern /*bool*/ int Join_internal(int ms, UInt32 handle);
+		
 		public void Join() {
-			// FIXME
+			if(state == ThreadState.Unstarted) {
+				throw new ThreadStateException("Thread has not been started");
+			}
+			
+			Thread thread=CurrentThread;
+				
+			thread.state |= ThreadState.WaitSleepJoin;
+			Join_internal(0, system_thread_handle);
+			thread.state &= ~ThreadState.WaitSleepJoin;
 		}
 
 		public bool Join(int millisecondsTimeout) {
 			if(millisecondsTimeout<0) {
 				throw new ArgumentException("Timeout less than zero");
 			}
-			// FIXME
-			return(false);
+			if(state == ThreadState.Unstarted) {
+				throw new ThreadStateException("Thread has not been started");
+			}
+
+			Thread thread=CurrentThread;
+				
+			thread.state |= ThreadState.WaitSleepJoin;
+			bool ret=(Join_internal(millisecondsTimeout,
+						system_thread_handle)==1);
+			thread.state &= ~ThreadState.WaitSleepJoin;
+
+			return(ret);
 		}
 
 		public bool Join(TimeSpan timeout) {
@@ -245,8 +287,18 @@ namespace System.Threading
 			if(timeout.Milliseconds < 0 || timeout.Milliseconds > Int32.MaxValue) {
 				throw new ArgumentOutOfRangeException("timeout out of range");
 			}
-			// FIXME
-			return(false);
+			if(state == ThreadState.Unstarted) {
+				throw new ThreadStateException("Thread has not been started");
+			}
+
+			Thread thread=CurrentThread;
+				
+			thread.state |= ThreadState.WaitSleepJoin;
+			bool ret=(Join_internal(timeout.Milliseconds,
+						system_thread_handle)==1);
+			thread.state &= ~ThreadState.WaitSleepJoin;
+
+			return(ret);
 		}
 
 		public void Resume() {
@@ -263,8 +315,15 @@ namespace System.Threading
 		private extern UInt32 Start_internal(ThreadStart start);
 		
 		public void Start() {
+			if(state!=ThreadState.Unstarted) {
+				throw new ThreadStateException("Thread has already been started");
+			}
+
+			state=ThreadState.Running;
+			
+			// Don't rely on system_thread_handle being
+			// set before start_delegate runs!
 			system_thread_handle=Start_internal(start_delegate);
-			// FIXME
 		}
 
 		public void Suspend() {

+ 5 - 0
mcs/class/corlib/System.Threading/ThreadState.cs

@@ -22,6 +22,9 @@ namespace System.Threading {
 		/// </summary>
 		Running = 0x00000000,
 
+		StopRequested = 0x00000001,
+		SuspendRequested = 0x00000002,
+		
 		/// <summary>
 		/// </summary>
 		Background = 0x00000004,
@@ -38,6 +41,8 @@ namespace System.Threading {
 		/// </summary>
 		WaitSleepJoin = 0x00000020,
 
+		Suspended = 0x00000040,
+
 		/// <summary>
 		/// </summary>
 		AbortRequested = 0x00000080,