unsafe override protected bool ReleaseHandle() { SafeCloseSocket socketHandle = _socketHandle; if (socketHandle != null && !socketHandle.IsInvalid) { // We are being finalized while the I/O operation associated // with the current overlapped is still pending (e.g. on app // domain shutdown). The socket has to be closed first to // avoid reuse after delete of the native overlapped structure. socketHandle.Dispose(); } // Release the native overlapped structure return(UnsafeCommonNativeMethods.LocalFree(handle) == IntPtr.Zero); }
internal SocketError ReplaceHandle() { // Copy out values from key options. The copied values should be kept in sync with the // handling in SafeCloseSocket.TrackOption. Note that we copy these values out first, before // we change _handle, so that we can use the helpers on Socket which internally access _handle. // Then once _handle is switched to the new one, we can call the setters to propagate the retrieved // values back out to the new underlying socket. bool broadcast = false, dontFragment = false, noDelay = false; int receiveSize = -1, receiveTimeout = -1, sendSize = -1, sendTimeout = -1; short ttl = -1; LingerOption linger = null; if (_handle.IsTrackedOption(TrackedSocketOptions.DontFragment)) { dontFragment = DontFragment; } if (_handle.IsTrackedOption(TrackedSocketOptions.EnableBroadcast)) { broadcast = EnableBroadcast; } if (_handle.IsTrackedOption(TrackedSocketOptions.LingerState)) { linger = LingerState; } if (_handle.IsTrackedOption(TrackedSocketOptions.NoDelay)) { noDelay = NoDelay; } if (_handle.IsTrackedOption(TrackedSocketOptions.ReceiveBufferSize)) { receiveSize = ReceiveBufferSize; } if (_handle.IsTrackedOption(TrackedSocketOptions.ReceiveTimeout)) { receiveTimeout = ReceiveTimeout; } if (_handle.IsTrackedOption(TrackedSocketOptions.SendBufferSize)) { sendSize = SendBufferSize; } if (_handle.IsTrackedOption(TrackedSocketOptions.SendTimeout)) { sendTimeout = SendTimeout; } if (_handle.IsTrackedOption(TrackedSocketOptions.Ttl)) { ttl = Ttl; } // Then replace the handle with a new one SafeCloseSocket oldHandle = _handle; SocketError errorCode = SocketPal.CreateSocket(_addressFamily, _socketType, _protocolType, out _handle); oldHandle.TransferTrackedState(_handle); oldHandle.Dispose(); if (errorCode != SocketError.Success) { return(errorCode); } // And put back the copied settings. For DualMode, we use the value stored in the _handle // rather than querying the socket itself, as on Unix stacks binding a dual-mode socket to // an IPv6 address may cause the IPv6Only setting to revert to true. if (_handle.IsTrackedOption(TrackedSocketOptions.DualMode)) { DualMode = _handle.DualMode; } if (_handle.IsTrackedOption(TrackedSocketOptions.DontFragment)) { DontFragment = dontFragment; } if (_handle.IsTrackedOption(TrackedSocketOptions.EnableBroadcast)) { EnableBroadcast = broadcast; } if (_handle.IsTrackedOption(TrackedSocketOptions.LingerState)) { LingerState = linger; } if (_handle.IsTrackedOption(TrackedSocketOptions.NoDelay)) { NoDelay = noDelay; } if (_handle.IsTrackedOption(TrackedSocketOptions.ReceiveBufferSize)) { ReceiveBufferSize = receiveSize; } if (_handle.IsTrackedOption(TrackedSocketOptions.ReceiveTimeout)) { ReceiveTimeout = receiveTimeout; } if (_handle.IsTrackedOption(TrackedSocketOptions.SendBufferSize)) { SendBufferSize = sendSize; } if (_handle.IsTrackedOption(TrackedSocketOptions.SendTimeout)) { SendTimeout = sendTimeout; } if (_handle.IsTrackedOption(TrackedSocketOptions.Ttl)) { Ttl = ttl; } return(SocketError.Success); }