diff options
author | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2004-08-31 22:22:47 +0400 |
---|---|---|
committer | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2004-08-31 22:22:47 +0400 |
commit | 04e11c49cc4b77838094f3c4dded5e90f16fae73 (patch) | |
tree | b229ac7635c960d718146687e418d23300733dfa | |
parent | 101f30c91ca33187afbf53eb048f0dd2759bb619 (diff) |
2004-08-27 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* HttpRuntime.cs: removed initializations to null in .cctor. Prevent
other requests from avoiding the lock if they are received before the
configuration system is inited. Ensure that the queue manager is not
null before using it (it can be null while the first request is being
processed).
svn path=/branches/mono-1-0/mcs/; revision=33115
-rw-r--r-- | mcs/class/System.Web/System.Web/ChangeLog | 12 | ||||
-rw-r--r-- | mcs/class/System.Web/System.Web/HttpRuntime.cs | 38 | ||||
-rw-r--r-- | mcs/class/System.Web/System.Web/QueueManager.cs | 52 |
3 files changed, 67 insertions, 35 deletions
diff --git a/mcs/class/System.Web/System.Web/ChangeLog b/mcs/class/System.Web/System.Web/ChangeLog index 90f1584d3f7..6aea602f750 100644 --- a/mcs/class/System.Web/System.Web/ChangeLog +++ b/mcs/class/System.Web/System.Web/ChangeLog @@ -1,3 +1,15 @@ + +2004-08-31 Gonzalo Paniagua Javier <gonzalo@ximian.com> + + * HttpRuntime.cs: initialize the response writer when finishing a + request because it cannot be queued. Under heavy load we made new + requests be processed before the ones that might be queued. This is + no longer the case. + + * QueueManager.cs: instead of queueing/dequeuing separately, we now + have a single method that does everything needed to decide which one + will be the next request processed. + 2004-08-27 Gonzalo Paniagua Javier <gonzalo@ximian.com> * HttpRuntime.cs: removed initializations to null in .cctor. Prevent diff --git a/mcs/class/System.Web/System.Web/HttpRuntime.cs b/mcs/class/System.Web/System.Web/HttpRuntime.cs index beb7048515c..9ebbf381c93 100644 --- a/mcs/class/System.Web/System.Web/HttpRuntime.cs +++ b/mcs/class/System.Web/System.Web/HttpRuntime.cs @@ -179,6 +179,8 @@ namespace System.Web { context.Response.FinalFlush (); } + /* + * This is not being used. OnFirstRequestEnd is empty. if (!_firstRequestExecuted) { lock (this) { if (!_firstRequestExecuted) { @@ -187,6 +189,7 @@ namespace System.Web { } } } + */ Interlocked.Decrement(ref _activeRequests); @@ -231,6 +234,7 @@ namespace System.Web { HttpContext context = new HttpContext (wr); HttpException exception = new HttpException (503, "Service unavailable"); Interlocked.Increment (ref _runtime._activeRequests); + context.Response.InitializeWriter (); _runtime.FinishRequest (context, exception); } @@ -276,7 +280,7 @@ namespace System.Web { _firstRequestStartTime = DateTime.Now; OnFirstRequestStart(context); _firstRequestStarted = true; - } + } } } @@ -311,38 +315,32 @@ namespace System.Web { void TryExecuteQueuedRequests () { // Wait for pending jobs to start - if (Interlocked.CompareExchange (ref pendingCallbacks, 3, 3) == 3) { - return; - } - - if (queueManager == null) - return; - - if (!queueManager.CanExecuteRequest (false)) { + if (Interlocked.CompareExchange (ref pendingCallbacks, 3, 3) == 3) return; - } - HttpWorkerRequest wr = queueManager.Dequeue (); - if (wr == null) { + HttpWorkerRequest wr = queueManager.GetNextRequest (null); + if (wr == null) return; - } Interlocked.Increment (ref pendingCallbacks); ThreadPool.QueueUserWorkItem (doRequestCallback, wr); TryExecuteQueuedRequests (); } - public static void ProcessRequest (HttpWorkerRequest Request) + public static void ProcessRequest (HttpWorkerRequest request) { - if (Request == null) - throw new ArgumentNullException ("Request"); + if (request == null) + throw new ArgumentNullException ("request"); QueueManager mgr = _runtime.queueManager; - if (!_runtime._firstRequestExecuted || mgr == null || mgr.CanExecuteRequest (false)) { - _runtime.InternalExecuteRequest (Request); - } else { - _runtime.queueManager.Queue (Request); + if (_runtime._firstRequestStarted && mgr != null) { + request = mgr.GetNextRequest (request); + // We're busy, return immediately + if (request == null) + return; } + + _runtime.InternalExecuteRequest (request); } #if NET_1_1 diff --git a/mcs/class/System.Web/System.Web/QueueManager.cs b/mcs/class/System.Web/System.Web/QueueManager.cs index a3f8f621d90..29ec8a91cc4 100644 --- a/mcs/class/System.Web/System.Web/QueueManager.cs +++ b/mcs/class/System.Web/System.Web/QueueManager.cs @@ -4,7 +4,7 @@ // Authors: // Gonzalo Paniagua Javier (gonzalo@ximian.com) // -// (C) 2003 Novell, Inc (http://www.novell.com) +// (C) 2003,2004 Novell, Inc (http://www.novell.com) // // @@ -53,35 +53,57 @@ namespace System.Web queue = new Queue (queueLimit); } - // TODO: handle local connections - public bool CanExecuteRequest (bool local) + // TODO: handle local connections, just check for 127.0.0.1 + bool CanExecuteRequest () { if (disposing) return false; int threads, cports; ThreadPool.GetAvailableThreads (out threads, out cports); - return (threads > minFree) || (local && threads > minLocalFree); + return (threads > minFree); // || (local && threads > minLocalFree); } - - public void Queue (HttpWorkerRequest wr) + + public HttpWorkerRequest GetNextRequest (HttpWorkerRequest req) { + if (!CanExecuteRequest ()) { + if (req != null) { + lock (queue) { + Queue (req); + } + } + + return null; + } + + HttpWorkerRequest result; lock (queue) { - if (queue.Count < queueLimit) { - queue.Enqueue (wr); - return; + result = Dequeue (); + if (result != null) { + if (req != null) + Queue (req); + } else { + result = req; } } + return result; + } + + void Queue (HttpWorkerRequest wr) + { + if (queue.Count < queueLimit) { + queue.Enqueue (wr); + return; + } + HttpRuntime.FinishUnavailable (wr); } - public HttpWorkerRequest Dequeue () + HttpWorkerRequest Dequeue () { - lock (queue) { - if (queue.Count > 0) - return (HttpWorkerRequest) queue.Dequeue (); - } + if (queue.Count > 0) + return (HttpWorkerRequest) queue.Dequeue (); return null; } @@ -93,7 +115,7 @@ namespace System.Web disposing = true; HttpWorkerRequest wr; - while ((wr = Dequeue ()) != null) + while ((wr = GetNextRequest (null)) != null) HttpRuntime.FinishUnavailable (wr); queue = null; |