예제 #1
0
        /// <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();
            }
        }
예제 #2
0
        /// <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();
            }
        }