|
8 | 8 | using Microsoft.Win32.SafeHandles; |
9 | 9 | using System.Reflection; |
10 | 10 | using System.Collections; |
| 11 | +using System.Threading; |
11 | 12 |
|
12 | 13 | namespace System.Net.Sockets |
13 | 14 | { |
@@ -108,7 +109,7 @@ internal void ReplaceHandleIfNecessaryAfterFailedConnect() |
108 | 109 | SocketError errorCode = ReplaceHandle(); |
109 | 110 | if (errorCode != SocketError.Success) |
110 | 111 | { |
111 | | - throw new SocketException((int) errorCode); |
| 112 | + throw new SocketException((int)errorCode); |
112 | 113 | } |
113 | 114 |
|
114 | 115 | _handle.LastConnectFailed = false; |
@@ -137,14 +138,22 @@ internal SocketError ReplaceHandle() |
137 | 138 |
|
138 | 139 | // Then replace the handle with a new one |
139 | 140 | SafeSocketHandle oldHandle = _handle; |
140 | | - SocketError errorCode = SocketPal.CreateSocket(_addressFamily, _socketType, _protocolType, out _handle); |
| 141 | + SocketError errorCode = SocketPal.CreateSocket(_addressFamily, _socketType, _protocolType, out SafeSocketHandle newHandle); |
| 142 | + Volatile.Write(ref _handle, newHandle); |
141 | 143 | oldHandle.TransferTrackedState(_handle); |
142 | 144 | oldHandle.Dispose(); |
| 145 | + |
143 | 146 | if (errorCode != SocketError.Success) |
144 | 147 | { |
145 | 148 | return errorCode; |
146 | 149 | } |
147 | 150 |
|
| 151 | + if (Volatile.Read(ref _disposed) != 0) |
| 152 | + { |
| 153 | + _handle.Dispose(); |
| 154 | + throw new ObjectDisposedException(GetType().FullName); |
| 155 | + } |
| 156 | + |
148 | 157 | // And put back the copied settings. For DualMode, we use the value stored in the _handle |
149 | 158 | // rather than querying the socket itself, as on Unix stacks binding a dual-mode socket to |
150 | 159 | // an IPv6 address may cause the IPv6Only setting to revert to true. |
|
0 commit comments