internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle handle = socketAndEventHandle._waitHandle.GetSafeWaitHandle(); bool b = false; try { handle.DangerousAddRef(ref b); } catch { if (b) { handle.DangerousRelease(); socketAndEventHandle._waitHandle = null; b = false; } } finally { if (b) { handle.Dispose(); } } }
internal static void CompleteInitialization(SafeCloseSocketAndEvent socketAndEventHandle) { SafeWaitHandle handle = socketAndEventHandle._waitHandle.GetSafeWaitHandle(); bool ignore = false; handle.DangerousAddRef(ref ignore); // TODO #3562: Investigate if this pattern is still correct. // Note that the handle still has a reference from the above DangerousAddRef. handle.Dispose(); }
internal static SafeCloseSocketAndEvent CreateWSASocketWithEvent(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, bool autoReset, bool signaled) { SafeCloseSocketAndEvent result = new SafeCloseSocketAndEvent(); CreateSocket(InnerSafeCloseSocket.CreateWSASocket(addressFamily, socketType, protocolType), result); if (result.IsInvalid) { throw new SocketException(); } result._waitHandle = new AutoResetEvent(false); CompleteInitialization(result); return result; }
internal static SafeCloseSocketAndEvent CreateWSASocketWithEvent(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, bool autoReset, bool signaled) { SafeCloseSocketAndEvent result = new SafeCloseSocketAndEvent(); CreateSocket(InnerSafeCloseSocket.CreateWSASocket(addressFamily, socketType, protocolType), result); if (result.IsInvalid) { throw new SocketException(); } result._waitHandle = new AutoResetEvent(false); CompleteInitialization(result); return(result); }
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions) { lock (s_callerArray) { // Setup changedEvent and native overlapped struct. if (s_ipv4Socket == null) { int blocking; // Sockets will be initialized by the call to OSSupportsIP*. if (Socket.OSSupportsIPv4) { blocking = -1; s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false); Interop.Winsock.ioctlsocket(s_ipv4Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking); s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle(); } if (Socket.OSSupportsIPv6) { blocking = -1; s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false); Interop.Winsock.ioctlsocket(s_ipv6Socket, Interop.Winsock.IoctlSocketConstants.FIONBIO, ref blocking); s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle(); } } if ((caller != null) && (!s_callerArray.ContainsKey(caller))) { s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null); } if (s_isListening || s_callerArray.Count == 0) { return; } if (!s_isPending) { int length; SocketError errorCode; if (Socket.OSSupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) != 0) { s_registeredWait = ThreadPool.RegisterWaitForSingleObject( s_ipv4WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv4, -1, true); errorCode = Interop.Winsock.WSAIoctl_Blocking( s_ipv4Socket.DangerousGetHandle(), (int)IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } SafeWaitHandle s_ipv4SocketGetEventHandleSafeWaitHandle = s_ipv4Socket.GetEventHandle().GetSafeWaitHandle(); errorCode = Interop.Winsock.WSAEventSelect( s_ipv4Socket, s_ipv4SocketGetEventHandleSafeWaitHandle, Interop.Winsock.AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } if (Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) != 0) { s_registeredWait = ThreadPool.RegisterWaitForSingleObject( s_ipv6WaitHandle, new WaitOrTimerCallback(AddressChangedCallback), StartIPOptions.StartIPv6, -1, true); errorCode = Interop.Winsock.WSAIoctl_Blocking( s_ipv6Socket.DangerousGetHandle(), (int)IOControlCode.AddressListChange, null, 0, null, 0, out length, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode != SocketError.Success) { NetworkInformationException exception = new NetworkInformationException(); if (exception.ErrorCode != (uint)SocketError.WouldBlock) { throw exception; } } SafeWaitHandle s_ipv6SocketGetEventHandleSafeWaitHandle = s_ipv6Socket.GetEventHandle().GetSafeWaitHandle(); errorCode = Interop.Winsock.WSAEventSelect( s_ipv6Socket, s_ipv6SocketGetEventHandleSafeWaitHandle, Interop.Winsock.AsyncEventBits.FdAddressListChange); if (errorCode != SocketError.Success) { throw new NetworkInformationException(); } } } s_isListening = true; s_isPending = true; } }