static void OnCloseHandle(IntPtr handle) { if (handle == IntPtr.Zero) { return; } ScheduleHandle 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 ScheduleHandle; nativeHandle.Free(); ((uv_handle_t *)handle)->data = IntPtr.Zero; Log.Trace($"{scheduleHandle?.GetType()} {handle} GCHandle released."); } } // Release memory Marshal.FreeHGlobal(handle); scheduleHandle?.SetHandleAsInvalid(); Log.Info($"{handle} memory and GCHandle released."); }
internal HandleContext( uv_handle_type handleType, Action <IntPtr> initializer, ScheduleHandle target) { Contract.Requires(initializer != null); Contract.Requires(target != null); int size = NativeMethods.GetSize(handleType); IntPtr handle = Marshal.AllocHGlobal(size); initializer(handle); GCHandle gcHandle = GCHandle.Alloc(target, GCHandleType.Normal); ((uv_handle_t *)handle)->data = GCHandle.ToIntPtr(gcHandle); this.Handle = handle; this.handleType = handleType; Log.Info($"{handleType} {handle} allocated."); }