/// <summary> /// Initializes a new instance of <see cref="CefBaseRefCounted{T}"/>. /// </summary> public unsafe CefBaseRefCounted() : base(Allocate(sizeof(T))) { var reference = new RefCountedReference(new WeakReference <CefBaseRefCounted>(this)); GlobalSyncRoot.EnterWriteLock(); try { RefCounted.Add(_instance, reference); } finally { GlobalSyncRoot.ExitWriteLock(); } }
/// <summary> /// Returns a wrapper for the specified pointer. /// </summary> /// <typeparam name="TClass">The type of wrapper.</typeparam> /// <param name="create">Represents a method that create a new wrapper.</param> /// <param name="instance">The pointer to ref-counted CEF struct.</param> /// <returns>Returns an existing or new wrapper for the specified pointer.</returns> public unsafe static TClass Wrap <TClass>(Func <IntPtr, TClass> create, T *instance) where TClass : CefBaseRefCounted <T> { if (instance == null) { return(null); } RefCountedWrapperStruct *ws = null; CefBaseRefCounted wrapper; IntPtr key = new IntPtr(instance); Internal.CefBaseRefCountedImpl.GlobalSyncRoot.EnterUpgradeableReadLock(); try { if (CefApi.UseUnsafeImplementation) { ws = GetWrapperStructPtr(instance); if (ws != null && UnsafeRefCounted.TryGetValue(ws->cppObject, out WeakReference <CefBaseRefCounted> weakRef) && weakRef.TryGetTarget(out wrapper)) { ((cef_base_ref_counted_t *)instance)->Release(); return((TClass)wrapper); } } if (RefCounted.TryGetValue(key, out RefCountedReference reference) && reference.Instance.TryGetTarget(out wrapper)) { ((cef_base_ref_counted_t *)instance)->Release(); return((TClass)wrapper); } #if DEBUG else if (CefStructure.IsAllocated(key)) { throw new InvalidCefObjectException(string.Format("Unexpected access to {0}.", typeof(TClass).Name)); } #endif else { Internal.CefBaseRefCountedImpl.GlobalSyncRoot.EnterWriteLock(); try { TClass typedWrapper = create(key); var weakRef = new WeakReference <CefBaseRefCounted>(typedWrapper); RefCounted[key] = new RefCountedReference(weakRef); if (ws != null) { UnsafeRefCounted[ws->cppObject] = weakRef; } return(typedWrapper); } finally { Internal.CefBaseRefCountedImpl.GlobalSyncRoot.ExitWriteLock(); } } } finally { Internal.CefBaseRefCountedImpl.GlobalSyncRoot.ExitUpgradeableReadLock(); } }