[Mono-bugs] [Bug 75826][Cri] New - Misbehavior and CPU race when closing down multiple listening tcp sockets

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Tue Aug 16 15:07:47 EDT 2005


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 jd.conley at coversant.net.

http://bugzilla.ximian.com/show_bug.cgi?id=75826

--- shadow/75826	2005-08-16 15:07:47.000000000 -0400
+++ shadow/75826.tmp.30597	2005-08-16 15:07:47.000000000 -0400
@@ -0,0 +1,112 @@
+Bug#: 75826
+Product: Mono: Class Libraries
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: Unknown
+Priority: Critical
+Component: System
+AssignedTo: mono-bugs at ximian.com                            
+ReportedBy: jd.conley at coversant.net               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Misbehavior and CPU race when closing down multiple listening tcp sockets
+
+Description of Problem:
+When a tcp socket is bound, listening, and in a BeginAccept(), closing it
+down causes a race condition which leads to a 100% CPU utilization.  This
+only happens when closing multiple listening sockets.
+
+
+Steps to reproduce the problem:
+1. Start more than one socket listening and in a BeginAccept.
+2. Close all the sockets in succession.
+
+(or run the test case and watch it fail)
+
+Actual Results:
+Watch the CPU spike and BeginAccept not get called on all the sockets.
+
+Expected Results:
+Sockets should close gracefully.
+
+How often does this happen? 
+Every time on my system.
+
+Test Case:
+namespace SocketListenerTests {
+
+[TestFixture()]
+class SocketTest {
+		[Test()]
+		public void BindSocketListenersAndBeginAccept()
+		{
+			//the number of socket listeners
+			const int NUM_SOCKETS = 10;
+
+			//whether or not we should make the test pass by side-stepping the race
+condition
+			const bool MAKE_IT_PASS = false;
+
+			//the wait events for each of the socket listeners
+			System.Threading.ManualResetEvent[] socketWaitEvents = new
+System.Threading.ManualResetEvent[NUM_SOCKETS];
+
+			System.Net.Sockets.Socket[] sockets = new
+System.Net.Sockets.Socket[NUM_SOCKETS];
+
+			//initialize all the listeners and start them listening
+			for (int i = 0; i < sockets.Length; i++)
+			{
+				System.Net.Sockets.Socket s = new
+System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork,
+																			System.Net.Sockets.SocketType.Stream,
+																			System.Net.Sockets.ProtocolType.Tcp);
+
+				s.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"),
+0));
+				s.Listen(int.MaxValue);
+
+				sockets[i] = s;
+
+				socketWaitEvents[i] = new System.Threading.ManualResetEvent(false);
+			}
+
+			//start accepting incoming connections (even though we wont get any)
+			for (int i = 0; i < sockets.Length; i++)
+			{
+				sockets[i].BeginAccept(BeginAcceptCallback, socketWaitEvents[i]);
+			}
+
+			//let the system digest everything we just told it to do
+			System.Threading.Thread.Sleep(50);
+
+			//close down all the listeners
+			for (int i = 0; i < sockets.Length; i++)
+			{
+				sockets[i].Close();
+
+				if (MAKE_IT_PASS)
+					System.Threading.Thread.Sleep(100);
+			}
+
+			//make sure that we get the beginacceptcallback for all the listeners
+			for (int i = 0; i < socketWaitEvents.Length; i++)
+			{
+				if (!socketWaitEvents[i].WaitOne(100, false))
+					Assertion.Fail("Timeout waiting for socket listener to get its
+callback.");
+			}
+		}
+
+		private void BeginAcceptCallback(IAsyncResult asyncResult)
+		{
+			((System.Threading.ManualResetEvent)asyncResult.AsyncState).Set();
+		}
+
+}
+}


More information about the mono-bugs mailing list