Socket.AcceptAsync shouldn't create new socket if SocketAsyncEventArgs.AcceptSocket...
authorMikhail Filippov <Mikhail.Filippov@jetbrains.com>
Mon, 25 Apr 2016 13:06:31 +0000 (16:06 +0300)
committerMikhail Filippov <Mikhail.Filippov@jetbrains.com>
Mon, 25 Apr 2016 13:06:31 +0000 (16:06 +0300)
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/System_test.dll.sources
mcs/class/System/Test/System.Net.Sockets/SocketAcceptAsyncTest.cs [new file with mode: 0644]

index 0f1c977a71d57169dc91c54c8baa329f65d18b38..b41d204ace8747f8b745660642c23d3998baf913 100644 (file)
@@ -991,16 +991,20 @@ namespace System.Net.Sockets
 
                static IOAsyncCallback BeginAcceptCallback = new IOAsyncCallback (ares => {
                        SocketAsyncResult sockares = (SocketAsyncResult) ares;
-                       Socket socket = null;
-
+                       Socket acc_socket = null;
                        try {
-                               socket = sockares.socket.Accept ();
+                               if (sockares.AcceptSocket == null) {
+                                       acc_socket = sockares.socket.Accept ();
+                               } else {
+                                       acc_socket = sockares.AcceptSocket;
+                                       sockares.socket.Accept (acc_socket);
+                               }
+
                        } catch (Exception e) {
                                sockares.Complete (e);
                                return;
                        }
-
-                       sockares.Complete (socket);
+                       sockares.Complete (acc_socket);
                });
 
                public IAsyncResult BeginAccept (int receiveSize, AsyncCallback callback, object state)
@@ -3427,7 +3431,9 @@ namespace System.Net.Sockets
                void InitSocketAsyncEventArgs (SocketAsyncEventArgs e, AsyncCallback callback, object state, SocketOperation operation)
                {
                        e.socket_async_result.Init (this, callback, state, operation);
-
+                       if (e.AcceptSocket != null) {
+                               e.socket_async_result.AcceptSocket = e.AcceptSocket;
+                       }
                        e.current_socket = this;
                        e.SetLastOperation (SocketOperationToSocketAsyncOperation (operation));
                        e.SocketError = SocketError.Success;
index 7d07dd75041141098ea61d99b056e993dc454d55..6ec32758faf518b7194ff3462876a81e2fc0610b 100644 (file)
@@ -247,6 +247,7 @@ System.Net.Sockets/MulticastOptionTest.cs
 System.Net.Sockets/NetworkStreamTest.cs
 System.Net.Sockets/TcpClientTest.cs
 System.Net.Sockets/TcpListenerTest.cs
+System.Net.Sockets/SocketAcceptAsyncTest.cs
 System.Net.Sockets/SocketTest.cs
 System.Net.Sockets/SocketAsyncEventArgsTest.cs
 System.Net.Sockets/SocketConnectAsyncTest.cs
diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketAcceptAsyncTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketAcceptAsyncTest.cs
new file mode 100644 (file)
index 0000000..6866ff5
--- /dev/null
@@ -0,0 +1,82 @@
+using System;
+using System.Threading;
+using System.Net;
+using System.Net.Sockets;
+using NUnit.Framework;
+
+namespace MonoTests.System.Net.Sockets
+{
+       [TestFixture]
+       public class SocketAcceptAsyncTest
+       {
+               private Socket _listenSocket;
+               private Socket _clientSocket;
+               private Socket _serverSocket;
+               private Socket _acceptedSocket;
+               private ManualResetEvent _readyEvent;
+               private ManualResetEvent _mainEvent;
+
+               [TestFixtureSetUp]
+               public void SetUp()
+               {
+                       _readyEvent = new ManualResetEvent(false);
+                       _mainEvent = new ManualResetEvent(false);
+
+                       ThreadPool.QueueUserWorkItem(_ => StartListen());
+                       if (!_readyEvent.WaitOne(1500))
+                               throw new TimeoutException();
+
+                       _clientSocket = new Socket(
+                               AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+                       _clientSocket.Connect(_listenSocket.LocalEndPoint);
+                       _clientSocket.NoDelay = true;
+               }
+
+               [TestFixtureTearDown]
+               public void TearDown()
+               {
+                       if (_acceptedSocket != null)
+                               _acceptedSocket.Close();
+                       if (_listenSocket != null)
+                               _listenSocket.Close();
+                       _readyEvent.Close();
+                       _mainEvent.Close();
+               }
+
+               private void StartListen()
+               {
+                       _listenSocket = new Socket(
+                               AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+                       _listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                       _listenSocket.Listen(1);
+
+                       _serverSocket = new Socket(
+                               AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+      var async = new SocketAsyncEventArgs();
+                       async.AcceptSocket = _serverSocket;
+                       async.Completed += (s, e) => OnAccepted(e);
+
+                       _readyEvent.Set();
+
+                       if (!_listenSocket.AcceptAsync(async))
+                               OnAccepted(async);
+               }
+
+               private void OnAccepted(SocketAsyncEventArgs e)
+               {
+                       _acceptedSocket = e.AcceptSocket;
+                       _mainEvent.Set();
+               }
+
+               [Test]
+               [Category("Test")]
+               public void AcceptAsyncShouldUseAcceptSocketFromEventArgs()
+               {
+                       if (!_mainEvent.WaitOne(1500))
+                               throw new TimeoutException();
+                       Assert.AreEqual(_serverSocket, _acceptedSocket);
+                       _mainEvent.Reset();
+               }
+       }
+}