Fix `Socket.ConnectAsync(SocketAsyncEventArgs)` behavior. (#15947)
commite92ecdc9ceb48d5b429e393b5cdeb5d75066fa1b
authorMartin Baulig <mabaul@microsoft.com>
Thu, 1 Aug 2019 10:31:25 +0000 (1 06:31 -0400)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 1 Aug 2019 10:31:25 +0000 (1 12:31 +0200)
tree5a400504e6ea189591563bcf05108d564cefdeb0
parent0e6965f6bab67a33d081762615dae22cb7779d4b
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.
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/System/System.Net.Sockets/SocketAsyncResult.cs
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
mcs/class/referencesource/System/net/System/Net/Sockets/_MultipleConnectAsync.cs