public void DetachFromIOCP(NativeHandle handle) { if (!this.tryDetachFromIOCP) { return; } // https://msdn.microsoft.com/en-us/library/windows/hardware/ff728840(v=vs.85).aspx const int FileReplaceCompletionInformation = 61; // https://msdn.microsoft.com/en-us/library/cc704588.aspx const uint STATUS_INVALID_INFO_CLASS = 0xC0000003; #pragma warning disable IDE0059 // 不需要赋值 var statusBlock = new IO_STATUS_BLOCK(); #pragma warning restore IDE0059 // 不需要赋值 IntPtr socket = IntPtr.Zero; _ = NativeMethods.uv_fileno(handle.Handle, ref socket); uint len = (uint)Marshal.SizeOf <FILE_COMPLETION_INFORMATION>(); if (NtSetInformationFile(socket, #pragma warning disable IDE0059 // 不需要赋值 out statusBlock, this.fileCompletionInfoPtr, len, #pragma warning restore IDE0059 // 不需要赋值 FileReplaceCompletionInformation) == STATUS_INVALID_INFO_CLASS) { // Replacing IOCP information is only supported on Windows 8.1 or newer this.tryDetachFromIOCP = false; } }
unsafe void OnConnectionCallback(int status) { NativeHandle client = null; Exception error = null; try { if (status < 0) { error = NativeMethods.CreateError((uv_err_code)status); } else { IntPtr loopHandle = ((uv_stream_t *)Handle)->loop; var loop = GetTarget <Loop>(loopHandle); client = new Tcp(loop); int result = NativeMethods.uv_accept(Handle, client.Handle); if (result < 0) { error = NativeMethods.CreateError((uv_err_code)result); } } } catch (Exception exception) { error = exception; } _nativeUnsafe.Accept(new RemoteConnection(client, error)); }
static void OnCloseHandle(IntPtr handle) { if (handle == IntPtr.Zero) { return; } NativeHandle nativeHandle = null; // Get gc handle first IntPtr pHandle = ((uv_handle_t *)handle)->data; if (pHandle != IntPtr.Zero) { GCHandle gcHandle = GCHandle.FromIntPtr(pHandle); if (gcHandle.IsAllocated) { nativeHandle = gcHandle.Target as NativeHandle; gcHandle.Free(); ((uv_handle_t *)handle)->data = IntPtr.Zero; } } // Release memory Marshal.FreeHGlobal(handle); nativeHandle?.OnClosed(); }
public Ping(NativeHandle sentHandle) : base(uv_req_type.UV_WRITE, 0) { this.sentHandle = sentHandle; byte[] array = PingBuf; this.Bufs = new uv_buf_t[1]; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); IntPtr arrayHandle = handle.AddrOfPinnedObject(); this.gcHandle = handle; this.Bufs[0] = new uv_buf_t(arrayHandle, array.Length); }
internal void DispatchHandle(NativeHandle handle) { if (0u >= (uint)_pipes.Count) { ThrowHelper.ThrowInvalidOperationException_Dispatch(); } int id = Interlocked.Increment(ref _requestId); Pipe pipe = _pipes[Math.Abs(id % _pipes.Count)]; _windowsApi.DetachFromIOCP(handle); pipe.Send(handle); }
internal void DispatchHandle(NativeHandle handle) { if (this.pipes.Count == 0) { throw new InvalidOperationException("No pipe connections to dispatch handles."); } int id = Interlocked.Increment(ref this.requestId); Pipe pipe = this.pipes[Math.Abs(id % this.pipes.Count)]; this.windowsApi.DetachFromIOCP(handle); pipe.Send(handle); }
static void OnWalkCallback(IntPtr handle, IntPtr loopHandle) { if (handle == IntPtr.Zero) { return; } try { // All handles must implement IDisposable var target = NativeHandle.GetTarget <IDisposable>(handle); target?.Dispose(); //Logger.Debug($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); } catch (Exception exception) { //Logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed. {exception}"); } }
internal void Send(NativeHandle serverHandle) { Debug.Assert(serverHandle != null); var ping = new Ping(serverHandle); uv_buf_t[] bufs = ping.Bufs; int result = NativeMethods.uv_write2( ping.Handle, this.Handle, bufs, bufs.Length, serverHandle.Handle, Ping.WriteCallback); if (result < 0) { ping.Dispose(); NativeMethods.ThrowOperationException((uv_err_code)result); } }
internal void Send(NativeHandle serverHandle) { Contract.Requires(serverHandle != null); var ping = new Ping(serverHandle); // Send the server handle once client is connected uv_buf_t[] bufs = ping.Bufs; int result = NativeMethods.uv_write2( ping.Handle, this.Handle, bufs, bufs.Length, serverHandle.Handle, Ping.WriteCallback); if (result < 0) { ping.Dispose(); throw NativeMethods.CreateError((uv_err_code)result); } }
public RemoteConnection(NativeHandle client, Exception error) { Client = client; Error = error; }