1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
5 using System.Diagnostics;
6 using System.Runtime.InteropServices;
7 using System.Threading;
8 using Microsoft.Win32.SafeHandles;
10 namespace System.Runtime.InteropServices.JavaScript
12 public abstract class AnyRef : SafeHandleMinusOneIsInvalid
14 private GCHandle? InFlight;
15 private int InFlightCounter;
16 private GCHandle AnyRefHandle;
17 public int JSHandle => (int)handle;
19 internal AnyRef(int jsHandle, bool ownsHandle) : this((IntPtr)jsHandle, ownsHandle)
22 internal AnyRef(IntPtr jsHandle, bool ownsHandle) : base(ownsHandle)
25 AnyRefHandle = GCHandle.Alloc(this, ownsHandle ? GCHandleType.Weak : GCHandleType.Normal);
29 internal int Int32Handle => (int)(IntPtr)AnyRefHandle;
31 internal void AddInFlight()
36 if (InFlightCounter == 1)
38 Debug.Assert(InFlight == null);
39 InFlight = GCHandle.Alloc(this, GCHandleType.Normal);
44 internal void ReleaseInFlight()
48 Debug.Assert(InFlightCounter != 0);
51 if (InFlightCounter == 0)
53 Debug.Assert(InFlight.HasValue);
54 InFlight.Value.Free();
61 protected void FreeGCHandle()
66 private int _refCount;
68 internal void AddRef()
70 Interlocked.Increment(ref _refCount);
73 internal void Release()
75 Debug.Assert(_refCount > 0, "AnyRefSafeHandle: Release() called more times than AddRef");
76 Interlocked.Decrement(ref _refCount);
79 internal int RefCount => _refCount;