Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baulig <mabaul@microsoft.com>2019-08-01 13:31:25 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2019-08-01 13:31:25 +0300
commite92ecdc9ceb48d5b429e393b5cdeb5d75066fa1b (patch)
tree5a400504e6ea189591563bcf05108d564cefdeb0 /mcs/class/referencesource
parent0e6965f6bab67a33d081762615dae22cb7779d4b (diff)
Fix `Socket.ConnectAsync(SocketAsyncEventArgs)` behavior. (#15947)
We need to clearly distinguish between synchronous and asynchronous completions and avoid any ambiguities and race conditions when it comes to error handling. On synchronous completion, we must not invoke the async completion delegate. In `System.Net.Sockets/Socket.cs`, the internal `BeginSConnect()` and `BeginMConnect()` now return a `bool` indicating whether or not an async operation is pending. If any error happens prior to starting the async operation, then we shall call `SocketAsyncResult.Complete(..., true)` and return `false`. And since this is a synchronous completion, it's `AsyncCallback` will not be invoked. In `referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs`, I compared the entire file against the CoreFX version and then copied the `AttemptConnection()` method from their implementation to adapt their behavior. The difference is that on synchronous completion, the `InternalConnectCallback(null, args)` should be invoked.
Diffstat (limited to 'mcs/class/referencesource')
-rw-r--r--mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs36
1 files changed, 28 insertions, 8 deletions
diff --git a/mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs b/mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs
index b8a4275b4e2..3d623fac590 100644
--- a/mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs
+++ b/mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs
@@ -219,28 +219,48 @@ namespace System.Net.Sockets
{
try
{
- Socket attemptSocket = null;
+ Socket attemptSocket;
IPAddress attemptAddress = GetNextAddress(out attemptSocket);
if (attemptAddress == null)
{
- return new SocketException(SocketError.NoData);
+ return new SocketException((int)SocketError.NoData);
}
- GlobalLog.Assert(attemptSocket != null, "MultipleConnectAsync.AttemptConnection: attemptSocket is null!");
-
internalArgs.RemoteEndPoint = new IPEndPoint(attemptAddress, endPoint.Port);
- if (!attemptSocket.ConnectAsync(internalArgs))
+ return AttemptConnection(attemptSocket, internalArgs);
+ }
+ catch (Exception e)
+ {
+ if (e is ObjectDisposedException)
+ {
+ NetEventSource.Fail(this, "unexpected ObjectDisposedException");
+ }
+ return e;
+ }
+ }
+
+ private Exception AttemptConnection(Socket attemptSocket, SocketAsyncEventArgs args)
+ {
+ try
+ {
+ if (attemptSocket == null)
+ {
+ NetEventSource.Fail(null, "attemptSocket is null!");
+ }
+
+ bool pending = attemptSocket.ConnectAsync(args);
+ if (!pending)
{
- return new SocketException(internalArgs.SocketError);
+ InternalConnectCallback(null, args);
}
}
catch (ObjectDisposedException)
{
- // This can happen if the user closes the socket, and is equivalent to a call
+ // This can happen if the user closes the socket, and is equivalent to a call
// to CancelConnectAsync
- return new SocketException(SocketError.OperationAborted);
+ return new SocketException((int)SocketError.OperationAborted);
}
catch (Exception e)
{