static void OnConnectionCallback(IntPtr handle, int status) { TcpStream server = HandleContext.GetTarget <TcpStream>(handle); if (server == null) { return; } TcpStream client = null; Exception error = null; try { if (status < 0) { error = NativeMethods.CreateError((uv_err_code)status); } else { client = server.NewStream(); // initialize internal buffer after we can access libuv // send/recv buffer sizes (which is after connecting) client.InitializeInternalBuffers(); } server.onServerConnect(client, error); } catch { client?.Dispose(); throw; } }
static void OnCloseHandle(IntPtr handle) { if (handle == IntPtr.Zero) { return; } TcpStream scheduleHandle = null; // Get gc handle first IntPtr pHandle = ((uv_handle_t *)handle)->data; if (pHandle != IntPtr.Zero) { GCHandle nativeHandle = GCHandle.FromIntPtr(pHandle); if (nativeHandle.IsAllocated) { scheduleHandle = nativeHandle.Target as TcpStream; nativeHandle.Free(); ((uv_handle_t *)handle)->data = IntPtr.Zero; } } // Release memory Marshal.FreeCoTaskMem(handle); scheduleHandle?.OnHandleClosed(); }
internal HandleContext( uv_handle_type handleType, Func <IntPtr, IntPtr, int> initializer, IntPtr loopHandle, TcpStream target) { if (loopHandle != IntPtr.Zero && initializer != null && target != null) { int size = NativeMethods.GetSize(handleType); IntPtr handle = Marshal.AllocCoTaskMem(size); try { int result = initializer(loopHandle, handle); NativeMethods.ThrowIfError(result); } catch (Exception) { Marshal.FreeCoTaskMem(handle); throw; } GCHandle gcHandle = GCHandle.Alloc(target, GCHandleType.Normal); ((uv_handle_t *)handle)->data = GCHandle.ToIntPtr(gcHandle); Handle = handle; this.handleType = handleType; //Logger.Log($"{handleType} {handle} allocated"); } else { throw new ArgumentException($"loopHandle {loopHandle}, initializer {initializer}, target {target} can't be null!"); } }
// creates a new TcpStream for a connecting client internal TcpStream NewStream() { TcpStream client = new TcpStream(loop); NativeMethods.StreamAccept(Handle, client.Handle); client.ReadStart(); //Logger.Log($"TcpStream {InternalHandle} client {client.InternalHandle} accepted."); return(client); }
// creates a new TcpStream for a connecting client internal unsafe TcpStream NewStream() { IntPtr loopHandle = ((uv_stream_t *)InternalHandle)->loop; Loop loop = HandleContext.GetTarget <Loop>(loopHandle); TcpStream client = new TcpStream(loop); NativeMethods.StreamAccept(InternalHandle, client.InternalHandle); client.ReadStart(); //Logger.Log($"{HandleType} {InternalHandle} client {client.InternalHandle} accepted."); return(client); }
static void OnConnectionCallback(IntPtr handle, int status) { // look up the C# TcpStream for this native handle if (nativeLookup.TryGetValue(handle, out NativeHandle entry)) { if (entry is TcpStream server) { TcpStream client = null; Exception error = null; try { if (status < 0) { error = NativeMethods.CreateError((uv_err_code)status); } else { client = server.NewStream(); // initialize internal buffer after we can access libuv // send/recv buffer sizes (which is after connecting) client.InitializeInternalBuffers(); } server.onServerConnect(client, error); } catch { client?.Dispose(); throw; } } else { Log.Error($"TcpStream.OnConnectionCallback: unexpected lookup type: {entry.GetType()}"); } } else { Log.Error($"TcpStream.OnConnectionCallback: nativeLookup no entry found for handle={handle}"); } }
static void OnAllocateCallback(IntPtr handle, IntPtr suggestedSize, out uv_buf_t buf) { TcpStream stream = HandleContext.GetTarget <TcpStream>(handle); buf = stream.readBufferStruct; }
static void OnReadCallback(IntPtr handle, IntPtr nread, ref uv_buf_t buf) { TcpStream stream = HandleContext.GetTarget <TcpStream>(handle); stream.OnReadCallback(stream.readBuffer, (int)nread.ToInt64()); }