// 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;
}
}
}