// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #define TRACE using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace Microsoft.AspNet.Server.Kestrel.Networking { /// /// Summary description for UvMemory /// public abstract class UvMemory : SafeHandle { protected Libuv _uv; private int _threadId; public UvMemory() : base(IntPtr.Zero, true) { } public Libuv Libuv { get { return _uv; } } public override bool IsInvalid { get { return handle == IntPtr.Zero; } } public int ThreadId { get { return _threadId; } private set { _threadId = value; } } unsafe protected void CreateMemory(Libuv uv, int threadId, int size) { _uv = uv; ThreadId = threadId; handle = Marshal.AllocCoTaskMem(size); *(IntPtr*)handle = GCHandle.ToIntPtr(GCHandle.Alloc(this, GCHandleType.Weak)); } unsafe protected static void DestroyMemory(IntPtr memory) { var gcHandlePtr = *(IntPtr*)memory; if (gcHandlePtr != IntPtr.Zero) { var gcHandle = GCHandle.FromIntPtr(gcHandlePtr); gcHandle.Free(); } Marshal.FreeCoTaskMem(memory); } internal IntPtr InternalGetHandle() { return handle; } public void Validate(bool closed = false) { Trace.Assert(closed || !IsClosed, "Handle is closed"); Trace.Assert(!IsInvalid, "Handle is invalid"); Trace.Assert(_threadId == Thread.CurrentThread.ManagedThreadId, "ThreadId is incorrect"); } unsafe public static THandle FromIntPtr(IntPtr handle) { GCHandle gcHandle = GCHandle.FromIntPtr(*(IntPtr*)handle); return (THandle)gcHandle.Target; } } }