Explorar o código

use delegate async invoke where posssible

svn path=/trunk/mcs/; revision=15684
Dietmar Maurer %!s(int64=22) %!d(string=hai) anos
pai
achega
c321eaca0f

+ 4 - 0
mcs/class/corlib/System.IO/ChangeLog

@@ -1,3 +1,7 @@
+2003-06-27  Dietmar Maurer  <[email protected]>
+
+	* Stream.cs: use async.delegate invoke 
+
 2003-06-18  Nick Drochak <[email protected]>
 
 	* FileSystemInfo.cs: Refresh cache when changeing file times.

+ 16 - 104
mcs/class/corlib/System.IO/Stream.cs

@@ -9,6 +9,7 @@
 //
 
 using System.Threading;
+using System.Runtime.Remoting.Messaging;
 
 namespace System.IO
 {
@@ -110,131 +111,42 @@ namespace System.IO
 			if (!CanRead)
 				throw new NotSupportedException ("This stream does not support reading");
 
-			SyncReadResult srr = new SyncReadResult (state);
-			try
-			{
-				srr.Complete (Read (buffer, offset, count));
-			}
-			catch (IOException e)
-			{
-				srr._exception = e;
-			}
+			ReadDelegate read_delegate = new ReadDelegate (Read);
 
-			if (cback != null)
-				cback (srr);
-
-			return srr;
+			return read_delegate.BeginInvoke (buffer, offset, count, cback, state);			
 		}
 
+		delegate void WriteDelegate (byte [] buffer, int offset, int count);
+
 		public virtual IAsyncResult
 		BeginWrite (byte [] buffer, int offset, int count, AsyncCallback cback, object state)
 		{
 			if (!CanWrite)
-				throw new NotSupportedException ("This stream does not support reading");
-
-			SyncWriteResult swr = new SyncWriteResult (state);
-			try
-			{
-				Write (buffer, offset, count);
-				swr.Complete ();
-			}
-			catch (IOException e)
-			{
-				swr._exception = e;
-			}
+				throw new NotSupportedException ("This stream does not support writing");
+	
+			WriteDelegate write_delegate = new WriteDelegate (Write);
 
-			if (cback != null)
-				cback (swr);
-
-			return swr;
+			return write_delegate.BeginInvoke (buffer, offset, count, cback, state);
 		}
 		
 		public virtual int EndRead (IAsyncResult async_result)
 		{
 			if (async_result == null)
 				throw new ArgumentNullException ("async_result");
-			SyncReadResult srr = async_result as SyncReadResult;
-			if (srr == null)
-				throw new ArgumentException ("async_result is invalid");
-			if (srr._fEndCalled)
-				throw new InvalidOperationException ("EndRead called twice");
-			srr._fEndCalled = true;
-			if (srr._exception != null)
-				throw srr._exception;
-			return srr._cbRead;
+
+			AsyncResult ar = (AsyncResult)async_result;
+			ReadDelegate read_delegate = (ReadDelegate)ar.AsyncDelegate;
+			return read_delegate.EndInvoke (async_result);
 		}
 
 		public virtual void EndWrite (IAsyncResult async_result)
 		{
 			if (async_result == null)
 				throw new ArgumentNullException ("async_result");
-			SyncWriteResult swr = async_result as SyncWriteResult;
-			if (swr == null)
-				throw new ArgumentException ("async_result is invalid");
-			if (swr._fEndCalled)
-				throw new InvalidOperationException ("EndRead called twice");
-			swr._fEndCalled = true;
-			if (swr._exception != null)
-				throw swr._exception;
-		}
-
-		// this class implements the synchronous IASyncResult for the obove methods
-		private class SyncResult : IAsyncResult
-		{
-			object _objState;		// client-supplied state
-			bool _fComplete;		// if the IO operation completed successfully
-			ManualResetEvent _hWait;		// the wait event
-			public bool _fEndCalled;		// true iff the End method was called already
-			public Exception _exception;	// holds any exception throw during IO operation
-
-			public SyncResult (object objState)
-			{
-				_objState = objState;
-				_hWait = new ManualResetEvent (false);
-			}
-
-			public void Complete ()
-			{
-				_fComplete = true;
-				_hWait.Set ();
-			}
-
-			// IAsyncResult members
-			object IAsyncResult.AsyncState
-			{
-				get { return _objState; }
-			}
-
-			WaitHandle IAsyncResult.AsyncWaitHandle
-			{
-				get { return _hWait; }
-			}
-
-			bool IAsyncResult.CompletedSynchronously
-			{
-				get { return true; }
-			}
 
-			bool IAsyncResult.IsCompleted
-			{
-				get { return _fComplete; }
-			}
-		}
-		private class SyncReadResult : SyncResult
-		{
-			public int _cbRead;		// the number of bytes read
-
-			public SyncReadResult (object objState) : base (objState) {}
-
-			public void Complete (int cbRead)
-			{
-				_cbRead = cbRead;
-				Complete ();
-			}
-		}
-		private class SyncWriteResult : SyncResult
-		{
-			public SyncWriteResult (object objState) : base (objState) {}
+			AsyncResult ar = (AsyncResult)async_result;
+			WriteDelegate write_delegate = (WriteDelegate)ar.AsyncDelegate;
+			write_delegate.EndInvoke (async_result);
 		}
 	}
 

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

@@ -1,3 +1,7 @@
+2003-06-27  Dietmar Maurer  <[email protected]>
+
+	* ThreadPool.cs: use async delegate invoke.
+
 2003-06-25  Dick Porter  <[email protected]>
 
 	* WaitHandle.cs: Default handle value should be InvalidHandle, not

+ 52 - 223
mcs/class/corlib/System.Threading/ThreadPool.cs

@@ -4,280 +4,109 @@
 // Author:
 //   Patrik Torstensson
 //   Dick Porter ([email protected])
+//   Maurer Dietmar ([email protected])
 //
 // (C) Ximian, Inc.  http://www.ximian.com
-// (C) Patrik Torstensson
 //
 using System;
 using System.Collections;
+using System.Runtime.CompilerServices;
 
 namespace System.Threading {
-	/// <summary> (Patrik T notes)
-	/// This threadpool is focused on saving resources not giving max performance. 
-	/// 
-	/// Note, this class is not perfect but it works. ;-) Should also replace
-	/// the queue with an internal one (performance)
-	/// 
-	/// This class should also use a specialized queue to increase performance..
-	/// </summary>
-	/// 
-	public sealed class ThreadPool {
-		internal struct ThreadPoolWorkItem {
-			public WaitCallback _CallBack;
-			public object _Context;
-		}
-
-		private int _ThreadTimeout;
-
-		private long _MaxThreads;
-		private long _CurrentThreads;
-		private long _ThreadsInUse;
-		private long _RequestInQueue;
-		private long _ThreadCreateTriggerRequests;
-
-		private Thread _MonitorThread;
-		private Queue _RequestQueue;
-
-		private ArrayList _Threads;
-		private ManualResetEvent _DataInQueue; 
-
-		static ThreadPool _Threadpool;
-
-		static ThreadPool() {
-			_Threadpool = new ThreadPool();
-		}
-
-		private ThreadPool() {
-			// 30 sec timeout default
-			_ThreadTimeout = 30 * 1000; 
-
-			// Used to signal that there is data in the queue
-			_DataInQueue = new ManualResetEvent(false);
-         
-			_Threads = ArrayList.Synchronized(new ArrayList());
-
-			// Holds requests..
-			_RequestQueue = Queue.Synchronized(new Queue(128));
-
-			// TODO: This should be 2 x number of CPU:s in the box
-			_MaxThreads = 16;
-			_CurrentThreads = 0;
-			_RequestInQueue = 0;
-			_ThreadsInUse = 0;
-			_ThreadCreateTriggerRequests = 5;
-
-			// TODO: This temp starts one thread, remove this..
-			CheckIfStartThread();
-
-			// Keeps track of requests in the queue and increases the number of threads if needed
-
-			// PT: Disabled - causes problems during shutdown
-			//_MonitorThread = new Thread(new ThreadStart(MonitorThread));
-			//_MonitorThread.Start();
-		}
 
-		internal void RemoveThread() {
-			Interlocked.Decrement(ref _CurrentThreads);
-			_Threads.Remove(Thread.CurrentThread);
-		}
-
-		internal void CheckIfStartThread() {
-			bool bCreateThread = false;
-
-			if (_CurrentThreads == 0) {
-				bCreateThread = true;
-			}
-
-			if ((	_MaxThreads == -1 || _CurrentThreads < _MaxThreads) && 
-				_ThreadsInUse > 0 && 
-				_RequestInQueue >= _ThreadCreateTriggerRequests) {
-				bCreateThread = true;
-			}
-
-			if (bCreateThread) {
-				Interlocked.Increment(ref _CurrentThreads);
-      
-				Thread Start = new Thread(new ThreadStart(WorkerThread));
-				Start.IsThreadPoolThreadInternal = true;
-				Start.IsBackground = true;
-				Start.Start();
-            
-				_Threads.Add(Start);
-			}
-		}
-
-		internal void AddItem(ref ThreadPoolWorkItem Item) {
-			_RequestQueue.Enqueue(Item);
-			if (Interlocked.Increment(ref _RequestInQueue) == 1) {
-				_DataInQueue.Set();
-			}
-		}
-
-		// Work Thread main function
-		internal void WorkerThread() {
-			bool bWaitForData = true;
-
-			while (true) {
-				if (bWaitForData) {
-					if (!_DataInQueue.WaitOne(_ThreadTimeout, false)) {
-						// Keep one thread running
-						if (_CurrentThreads > 1) {
-							// timeout
-							RemoveThread();
-							return;
-						}
-						continue;
-					}
-				}
-
-				Interlocked.Increment(ref _ThreadsInUse);
-
-				// TODO: Remove when we know how to stop the watch thread
-				CheckIfStartThread();
-
-				try {
-					ThreadPoolWorkItem oItem = (ThreadPoolWorkItem) _RequestQueue.Dequeue();
-
-					if (Interlocked.Decrement(ref _RequestInQueue) == 0) {
-						_DataInQueue.Reset();
-					}
+	public sealed class ThreadPool {
 
-					oItem._CallBack(oItem._Context);
-				}
-				catch (InvalidOperationException) {
-					// Queue empty
-					bWaitForData = true;
-				}
-				catch (ThreadAbortException) {
-					// We will leave here.. (thread abort can't be handled)
-					RemoveThread();
-				}
-				finally {
-					Interlocked.Decrement(ref _ThreadsInUse);
-				}
-			}
+		private ThreadPool ()
+		{
+			/* nothing to do */
 		}
-		
-		/* This is currently not in use
-		 
-		internal void MonitorThread() {
-			while (true) {
-			if (_DataInQueue.WaitOne ()) {
-				CheckIfStartThread();
-			}
 
-			Thread.Sleep(500);
-			}
+		public static bool BindHandle (IntPtr osHandle)
+		{
+			throw new NotSupportedException("This is MS specific");
 		}
 		
-		*/
-		internal bool QueueUserWorkItemInternal(WaitCallback callback) {
-			return QueueUserWorkItem(callback, null);
-		}
-
-		internal bool QueueUserWorkItemInternal(WaitCallback callback, object context) {
-			ThreadPoolWorkItem Item = new ThreadPoolWorkItem();
-
-			Item._CallBack = callback;
-			Item._Context = context;
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		public static extern void GetAvailableThreads (out int workerThreads, out int completionPortThreads);
 
-			AddItem(ref Item);
-
-			// LAMESPEC: Return value? should use exception here if anything goes wrong
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		public static extern void GetMaxThreads (out int workerThreads, out int completionPortThreads);
+			
+		public static bool QueueUserWorkItem (WaitCallback callback)
+		{
+			IAsyncResult ar = callback.BeginInvoke (null, null, null);
+			if (ar == null)
+				return false;
 			return true;
 		}
 
-		public static bool BindHandle(IntPtr osHandle) {
-			throw new NotSupportedException("This is a win32 specific method, not supported Mono");
-		}
-
-		public static bool QueueUserWorkItem(WaitCallback callback) {
-			return _Threadpool.QueueUserWorkItemInternal(callback);
-		}
-
-		public static bool QueueUserWorkItem(WaitCallback callback, object state) {
-			return _Threadpool.QueueUserWorkItemInternal(callback, state);
-		}
-
-		public static bool UnsafeQueueUserWorkItem(WaitCallback callback, object state) {
-			return _Threadpool.QueueUserWorkItemInternal(callback, state);
-		}
-
-		static TimeSpan GetTSFromMS (long ms)
+		public static bool QueueUserWorkItem (WaitCallback callback, object state)
 		{
-			if (ms < -1)
-				throw new ArgumentOutOfRangeException ("millisecondsTimeOutInterval", "timeout < -1");
-
-			return new TimeSpan (0, 0, 0, 0, (int) ms);
+			IAsyncResult ar = callback.BeginInvoke (state, null, null);
+			if (ar == null)
+				return false;
+			return true;
 		}
 
 		public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-										WaitOrTimerCallback callback,
+										WaitOrTimerCallback callBack,
 										object state,
 										int millisecondsTimeOutInterval,
 										bool executeOnlyOnce)
 		{
-			TimeSpan ts = GetTSFromMS ((long) millisecondsTimeOutInterval);
-			return RegisterWaitForSingleObject (waitObject, callback, state, ts, executeOnlyOnce);
+			return RegisterWaitForSingleObject (waitObject, callBack, state,
+							    (long) millisecondsTimeOutInterval, executeOnlyOnce);
 		}
 
 		public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-										WaitOrTimerCallback callback,
+										WaitOrTimerCallback callBack,
 										object state,
 										long millisecondsTimeOutInterval,
 										bool executeOnlyOnce)
 		{
-			TimeSpan ts = GetTSFromMS (millisecondsTimeOutInterval);
-			return RegisterWaitForSingleObject (waitObject, callback, state, ts, executeOnlyOnce);
+			if (millisecondsTimeOutInterval < -1)
+				throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
+
+			if (millisecondsTimeOutInterval > Int32.MaxValue)
+				throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
+
+			TimeSpan timeout = new TimeSpan (0, 0, 0, 0, (int) millisecondsTimeOutInterval);
+			
+			RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callBack, state,
+										timeout, executeOnlyOnce);
+			QueueUserWorkItem (new WaitCallback (waiter.Wait), null);
+			return waiter;
 		}
 
 		public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-										WaitOrTimerCallback callback,
+										WaitOrTimerCallback callBack,
 										object state,
 										TimeSpan timeout,
 										bool executeOnlyOnce)
 		{
-			long ms = (long) timeout.TotalMilliseconds;
-			if (ms < -1)
-				throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
-
-			if (ms > Int32.MaxValue)
-				throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
+			return RegisterWaitForSingleObject (waitObject, callBack, state,
+							    (long) timeout.TotalMilliseconds, executeOnlyOnce);
 
-			RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callback, state, timeout, executeOnlyOnce);
-			_Threadpool.QueueUserWorkItemInternal (new WaitCallback (waiter.Wait), null);
-			return waiter;
 		}
 
 		[CLSCompliant(false)]
 		public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
-										WaitOrTimerCallback callback,
+										WaitOrTimerCallback callBack,
 										object state,
 										uint millisecondsTimeOutInterval,
 										bool executeOnlyOnce)
 		{
-			TimeSpan ts = GetTSFromMS ((long) millisecondsTimeOutInterval);
-			return RegisterWaitForSingleObject (waitObject, callback, state, ts, executeOnlyOnce);
-		}
-
-		[MonoTODO]
-		public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce) {
-			throw new NotImplementedException();
-		}
-
-		[MonoTODO]
-		public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce) {
-			throw new NotImplementedException();
+			return RegisterWaitForSingleObject (waitObject, callBack, state,
+							    (long) millisecondsTimeOutInterval, executeOnlyOnce);
 		}
 
-		[MonoTODO]
-		public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, TimeSpan timeout, bool executeOnlyOnce) {
-			throw new NotImplementedException();
+		public static bool UnsafeQueueUserWorkItem (WaitCallback callback, object state)
+		{
+			IAsyncResult ar = callback.BeginInvoke (state, null, null);
+			if (ar == null)
+				return false;
+			return true;
 		}
 
-		[CLSCompliant(false)][MonoTODO]
-		public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) {
-			throw new NotImplementedException();
-		}
 	}
 }