[Mono-bugs] [Bug 78365][Min] New - HttpListener misses its requests
bugzilla-daemon at bugzilla.ximian.com
bugzilla-daemon at bugzilla.ximian.com
Thu May 11 03:24:14 EDT 2006
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by pawel.sakowski at mind-breeze.com.
http://bugzilla.ximian.com/show_bug.cgi?id=78365
--- shadow/78365 2006-05-11 03:24:14.000000000 -0400
+++ shadow/78365.tmp.17419 2006-05-11 03:24:14.000000000 -0400
@@ -0,0 +1,139 @@
+Bug#: 78365
+Product: Mono: Class Libraries
+Version: 1.1
+OS: GNU/Linux [Other]
+OS Details:
+Status: NEW
+Resolution:
+Severity:
+Priority: Minor
+Component: System
+AssignedTo: mono-bugs at ximian.com
+ReportedBy: pawel.sakowski at mind-breeze.com
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: HttpListener misses its requests
+
+Description of Problem:
+When put under a stress load, the HttpListener randomly fails to answer
+some HTTP requests, eventually leading to a client timeout.
+
+Steps to reproduce the problem:
+1. Compile the server:
+using System;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+class Server
+{
+ static void Main()
+ {
+
+ HttpListener l = new HttpListener();
+ l.Prefixes.Add("http://*:8765/");
+ l.Start();
+
+ while (true)
+ {
+ HttpListenerContext ctx = l.GetContext();
+ new Thread(handle).Start(ctx);
+ }
+
+ }
+ static byte[] buf = new byte[20000];
+ static void handle(object o)
+ {
+
+ HttpListenerContext ctx = (HttpListenerContext)o;
+ Stream stream = ctx.Request.InputStream;
+ stream.Read(buf, 0, buf.Length);
+ stream.Close();
+ HttpListenerResponse r = ctx.Response;
+ r.StatusCode = 200;
+ r.ContentLength64 = 0;
+ Stream outputStream = r.OutputStream;
+ outputStream.Write(buf, 0, 0);
+ outputStream.Close();
+ r.Close();
+
+ }
+}
+
+2. Compile the client:
+using System;
+using System.Net;
+using System.IO;
+using System.Threading;
+public class Client
+{
+ static void Main()
+ {
+ for (uint i = 0; i < 10; i++)
+ {
+ new Thread(go).Start();
+ }
+ go();
+ }
+ static void go()
+ {
+ Uri uri = new Uri("http://127.0.0.1:8765");
+ byte[] buf = new byte[10039 + 12];
+ int length = 200;
+ uint seq = 0;
+ Array.Copy(BitConverter.GetBytes(Thread.CurrentThread.ManagedThreadId),
+buf, 4);
+ while (true)
+ {
+ try
+ {
+ Array.Copy(BitConverter.GetBytes(seq), 0, buf, 8, 4);
+ WebRequest req = WebRequest.CreateDefault(uri);
+ req.Method = "POST";
+ req.ContentLength = length;
+ Stream stream = req.GetRequestStream();
+ stream.Write(buf, 0, length);
+ stream.Close();
+ WebResponse response = req.GetResponse();
+ response.Close();
+ length = 12 + ((length - 12) + 103) % (buf.Length - 12);
+ seq++;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Thread " +
+Thread.CurrentThread.ManagedThreadId.ToString("x") + " seq " + seq + ": " +
+ex);
+ }
+ }
+ }
+}
+
+3. Invoke both.
+4. Wait about 30 minutes.
+
+Actual Results:
+Thread b6efdbb0 seq 13660: System.Net.WebException: The request timed out
+in <0x000bf> System.Net.HttpWebRequest:GetRequestStream ()
+in <0x00121> Client:go ()
+[several times, the numbers obviously vary]
+
+Expected Results:
+No exception thrown over an arbitrary time period.
+
+How often does this happen?
+Virtually always reproduces in under 1 hour.
+
+Additional Information:
+Ad-hoc locking in HttpListener.cs leads to a race condition. If a new
+request arrives while BeginGetContext gets after the "lock (ctx_queue)"
+line, but before the "lock (wait_queue)" line:
+
+- RegisterContext adds the new HttpListenerContext to ctx_queue,
+- BeginGetContext adds the ListenerAsyncResult to wait_queue,
+- the two never meet.
+
+Theoretically at any point at least one of the queues should be empty; this
+condition is violated in the above situation.
More information about the mono-bugs
mailing list