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