// 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; using Microsoft.AspNet.Server.Kestrel.Infrastructure; namespace Microsoft.AspNet.Server.Kestrel.Networking { /// /// Summary description for UvMemory /// public abstract class UvMemory : SafeHandle { protected Libuv _uv; protected int _threadId; protected readonly IKestrelTrace _log; protected UvMemory(IKestrelTrace logger) : base(IntPtr.Zero, true) { _log = logger; } 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; DestroyMemory(memory, gcHandlePtr); } unsafe protected static void DestroyMemory(IntPtr memory, IntPtr gcHandlePtr) { 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) { Debug.Assert(closed || !IsClosed, "Handle is closed"); Debug.Assert(!IsInvalid, "Handle is invalid"); Debug.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; } } }