private static unsafe void CreateSocket() { Debug.Assert(Monitor.IsEntered(s_gate)); Debug.Assert(Socket == null, "Socket is not null, must close existing socket before opening another."); var sh = new SafeSocketHandle(); IntPtr newSocket; Interop.Error result = Interop.Sys.CreateNetworkChangeListenerSocket(&newSocket); if (result != Interop.Error.SUCCESS) { string message = Interop.Sys.GetLastErrorInfo().GetErrorMessage(); sh.Dispose(); throw new NetworkInformationException(message); } Marshal.InitHandle(sh, newSocket); Socket = new Socket(sh); // Don't capture ExecutionContext. ThreadPool.UnsafeQueueUserWorkItem(
public void Dispose() { _handle.Dispose(); }
public ValueTask UnbindAsync(CancellationToken cancellationToken = default) { _listenSocket?.Dispose(); _socketHandle?.Dispose(); return(default);
public async Task SendFileGetsCanceledByDispose(bool owning) { // Aborting sync operations for non-owning handles is not supported on Unix. if (!owning && UsesSync && !PlatformDetection.IsWindows) { return; } // We try this a couple of times to deal with a timing race: if the Dispose happens // before the operation is started, the peer won't see a ConnectionReset SocketException and we won't // see a SocketException either. int msDelay = 100; await RetryHelper.ExecuteAsync(async() => { (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair(); using SafeSocketHandle? owner = ReplaceWithNonOwning(ref socket1, owning); using (socket2) { Task socketOperation = Task.Run(async() => { // Create a large file that will cause SendFile to block until the peer starts reading. using var tempFile = TempFile.Create(); using (var fs = new FileStream(tempFile.Path, FileMode.CreateNew, FileAccess.Write)) { fs.SetLength(20 * 1024 * 1024 /* 20MB */); } await SendFileAsync(socket1, tempFile.Path); }); // Wait a little so the operation is started. await Task.Delay(msDelay); msDelay *= 2; Task disposeTask = Task.Run(() => socket1.Dispose()); await Task.WhenAny(disposeTask, socketOperation).WaitAsync(TimeSpan.FromSeconds(30)); await disposeTask; SocketError?localSocketError = null; try { await socketOperation; } catch (SocketException se) { localSocketError = se.SocketErrorCode; } if (UsesSync) { Assert.Equal(SocketError.ConnectionAborted, localSocketError); } else { Assert.Equal(SocketError.OperationAborted, localSocketError); } owner?.Dispose(); // On OSX, we're unable to unblock the on-going socket operations and // perform an abortive close. if (!(UsesSync && PlatformDetection.IsOSXLike)) { SocketError?peerSocketError = null; var receiveBuffer = new byte[4096]; while (true) { try { int received = socket2.Receive(receiveBuffer); if (received == 0) { break; } } catch (SocketException se) { peerSocketError = se.SocketErrorCode; break; } } Assert.Equal(SocketError.ConnectionReset, peerSocketError); } } }, maxAttempts : 10, retryWhen : e => e is XunitException); }