Exemple #1
0
        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>A hash code for the <see cref="cef_v8value_t"/> object.</returns>
        public override int GetHashCode()
        {
            if (IsValid() == 0)
                return(0);

            fixed(cef_v8value_t *self = &this)
            {
                RefCountedWrapperStruct *ws     = RefCountedWrapperStruct.FromRefCounted(self);
                V8ValueImplLayout *      cppobj = ((V8ValueImplLayout *)(ws->cppObject));

                switch (cppobj->Type)
                {
                case CefV8ValueType.Object:
                    V8ValueImplHandleLayout *v8ValueHandle = cppobj->handle;
                    if (v8ValueHandle == null)
                    {
                        return(0);
                    }
                    IntPtr *handle = v8ValueHandle->handle;
                    return((handle != null) ? (*handle).GetHashCode() : 0);

                case CefV8ValueType.Bool:
                    return(cppobj->value.bool_value_ | (int)CefV8ValueType.Bool);

                case CefV8ValueType.Double:
                    return(cppobj->value.double_value_.GetHashCode());

                case CefV8ValueType.Int:
                case CefV8ValueType.UInt:
                    return(cppobj->value.int_value_);

                case CefV8ValueType.Null:
                case CefV8ValueType.Undefined:
                    return((int)cppobj->Type);

                case CefV8ValueType.String:
                    return(cppobj->value.string_value_.GetHashCode());

                case CefV8ValueType.Date:
                    return(cppobj->value.date_value_.GetHashCode());
                }
            }

            return(0);
        }
#pragma warning disable CS1591
        protected unsafe override void Dispose(bool disposing)
        {
            IntPtr key = Volatile.Read(ref _instance);

            if (key != IntPtr.Zero)
            {
                GlobalSyncRoot.EnterWriteLock();
                try
                {
                    if (CefApi.UseUnsafeImplementation)
                    {
                        RefCountedWrapperStruct *ws = GetWrapperStructPtr((void *)key);
                        if (ws != null)
                        {
                            UnsafeRefCounted.Remove(ws->cppObject);
                        }
                    }
                    RefCounted.Remove(key);
                }
                finally
                {
                    GlobalSyncRoot.ExitWriteLock();
                }
#if NETFRAMEWORK
                if (Environment.HasShutdownStarted)
                {
                    if (CefStructure.IsAllocated(key))                     // allow leaks to fix potential UAF
                    {
                        return;
                    }
                }
                else
#endif
                if (CefStructure.Free(key))
                {
                    return;
                }

                base.Dispose(disposing);
            }
        }
        /// <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();
            }
        }