From f8db5bce9f25e132d1814e5d560e957136bc416e Mon Sep 17 00:00:00 2001 From: Johan Laanstra Date: Thu, 25 Jan 2024 10:19:13 -0800 Subject: [PATCH] Remove Resurrect logic as it shouldn't be needed for .NET 6 and newer. (#1380) * Remove Resurrect logic as it shouldn't be needed for .NET 6 and newer. * Remove double check. * Add check back. --- src/WinRT.Runtime/ComWrappersSupport.net5.cs | 16 +- src/WinRT.Runtime/IWinRTObject.net5.cs | 18 -- src/WinRT.Runtime/ObjectReference.cs | 262 +++++++++---------- 3 files changed, 118 insertions(+), 178 deletions(-) diff --git a/src/WinRT.Runtime/ComWrappersSupport.net5.cs b/src/WinRT.Runtime/ComWrappersSupport.net5.cs index 492de65db..855be7593 100644 --- a/src/WinRT.Runtime/ComWrappersSupport.net5.cs +++ b/src/WinRT.Runtime/ComWrappersSupport.net5.cs @@ -116,12 +116,6 @@ internal static unsafe InspectableInfo GetInspectableInfo(IntPtr pThis) // We need to do the same thing for System.Type because there can be multiple WUX.Interop.TypeName's // for a single System.Type. - // Resurrect IWinRTObject's disposed IObjectReferences, if necessary - if (rcw is IWinRTObject winrtObj) - { - winrtObj.Resurrect(); - } - return rcw switch { ABI.System.Nullable nt => (T)nt.Value, @@ -161,15 +155,7 @@ public static void RegisterObjectForInterface(object obj, IntPtr thisPtr) => public static object TryRegisterObjectForInterface(object obj, IntPtr thisPtr) { - var rcw = ComWrappers.GetOrRegisterObjectForComInstance(thisPtr, CreateObjectFlags.TrackerObject, obj); - - // Resurrect IWinRTObject's disposed IObjectReferences, if necessary - var target = rcw is Delegate del ? del.Target : rcw; - if (target is IWinRTObject winrtObj) - { - winrtObj.Resurrect(); - } - return rcw; + return ComWrappers.GetOrRegisterObjectForComInstance(thisPtr, CreateObjectFlags.TrackerObject, obj); } public static IObjectReference CreateCCWForObject(object obj) diff --git a/src/WinRT.Runtime/IWinRTObject.net5.cs b/src/WinRT.Runtime/IWinRTObject.net5.cs index edc26e8ef..cde5326ee 100644 --- a/src/WinRT.Runtime/IWinRTObject.net5.cs +++ b/src/WinRT.Runtime/IWinRTObject.net5.cs @@ -184,23 +184,5 @@ object GetOrCreateTypeHelperData(RuntimeTypeHandle type, Func helperData { return AdditionalTypeData.GetOrAdd(type, (type) => helperDataFactory()); } - - internal void Resurrect() - { - if (NativeObject.Resurrect()) - { - foreach (var cached in QueryInterfaceCache) - { - cached.Value.Resurrect(); - } - - // Delegates store their agile reference as an additional type data. - // These should be recreated when instances are resurrect. - if (AdditionalTypeData.TryGetValue(typeof(AgileReference).TypeHandle, out var agileObj)) - { - AdditionalTypeData.TryUpdate(typeof(AgileReference).TypeHandle, new AgileReference(NativeObject), agileObj); - } - } - } } } \ No newline at end of file diff --git a/src/WinRT.Runtime/ObjectReference.cs b/src/WinRT.Runtime/ObjectReference.cs index 566049a4c..137e239ef 100644 --- a/src/WinRT.Runtime/ObjectReference.cs +++ b/src/WinRT.Runtime/ObjectReference.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -38,15 +38,15 @@ public IntPtr ThisPtr public bool IsFreeThreaded => GetContextToken() == IntPtr.Zero; - public bool IsInCurrentContext - { - get - { - var contextToken = GetContextToken(); - return contextToken == IntPtr.Zero || contextToken == Context.GetContextToken(); - } - } - + public bool IsInCurrentContext + { + get + { + var contextToken = GetContextToken(); + return contextToken == IntPtr.Zero || contextToken == Context.GetContextToken(); + } + } + private protected IntPtr ThisPtrFromOriginalContext { get @@ -134,15 +134,15 @@ protected IObjectReference(IntPtr thisPtr) Dispose(false); } - public ObjectReference As< -#if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)] + public ObjectReference As< +#if NET + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)] #endif T>() => As(GuidGenerator.GetIID(typeof(T))); - public unsafe ObjectReference As< + public unsafe ObjectReference As< #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] #endif T>(Guid iid) { @@ -173,24 +173,24 @@ public unsafe TInterface AsInterface() #endif } - public int TryAs< + public int TryAs< #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)] #endif T>(out ObjectReference objRef) => TryAs(GuidGenerator.GetIID(typeof(T)), out objRef); - public unsafe int TryAs< + public unsafe int TryAs< #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] #endif T>(Guid iid, out ObjectReference objRef) { // Check the marker interface for ObjectReferenceWithContext. If that is the case, we inline // the special logic for such objects. This avoids having to use a generic virtual method here, // which would just explode the binary size on NativeAOT due to combinatorial generics. - if (this is IObjectReferenceWithContext) - { - return ObjectReferenceWithContext.TryAs(this, iid, out objRef); + if (this is IObjectReferenceWithContext) + { + return ObjectReferenceWithContext.TryAs(this, iid, out objRef); } // Normal path for IObjectReference or any IObjectReference @@ -287,22 +287,6 @@ protected virtual void Dispose(bool disposing) } } - internal bool Resurrect() - { - lock (_disposedLock) - { - if (!disposed) - { - return false; - } - disposed = false; - ResurrectTrackerSource(); - AddRef(); - GC.ReRegisterForFinalize(this); - return true; - } - } - protected virtual unsafe void AddRef(bool refFromTrackerSource) { Marshal.AddRef(ThisPtr); @@ -353,18 +337,6 @@ internal unsafe void ReleaseFromTrackerSource() } } - private unsafe void ResurrectTrackerSource() - { - if (ReferenceTrackerPtr != IntPtr.Zero) - { - Marshal.AddRef(ReferenceTrackerPtr); - if (!PreventReleaseFromTrackerSourceOnDispose) - { - ReferenceTracker.AddRefFromTrackerSource(ReferenceTrackerPtr); - } - } - } - private unsafe void DisposeTrackerSource() { if (ReferenceTrackerPtr != IntPtr.Zero) @@ -382,9 +354,9 @@ private protected virtual IntPtr GetThisPtrForCurrentContext() return ThisPtrFromOriginalContext; } - private protected virtual IntPtr GetContextToken() - { - return IntPtr.Zero; + private protected virtual IntPtr GetContextToken() + { + return IntPtr.Zero; } public ObjectReferenceValue AsValue() @@ -412,7 +384,7 @@ public unsafe ObjectReferenceValue AsValue(Guid iid) #else public #endif - class ObjectReference< + class ObjectReference< #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] #endif @@ -446,20 +418,20 @@ public static ObjectReference Attach(ref IntPtr thisPtr) return null; } - if (ComWrappersSupport.IsFreeThreaded(thisPtr)) - { + if (ComWrappersSupport.IsFreeThreaded(thisPtr)) + { var obj = new ObjectReference(thisPtr); thisPtr = IntPtr.Zero; - return obj; + return obj; } - else - { + else + { var obj = new ObjectReferenceWithContext( thisPtr, Context.GetContextCallback(), Context.GetContextToken()); thisPtr = IntPtr.Zero; - return obj; + return obj; } } @@ -470,21 +442,21 @@ public static ObjectReference Attach(ref IntPtr thisPtr, Guid iid) return null; } - if (ComWrappersSupport.IsFreeThreaded(thisPtr)) - { + if (ComWrappersSupport.IsFreeThreaded(thisPtr)) + { var obj = new ObjectReference(thisPtr); thisPtr = IntPtr.Zero; - return obj; + return obj; } - else - { + else + { var obj = new ObjectReferenceWithContext( thisPtr, Context.GetContextCallback(), Context.GetContextToken(), iid); thisPtr = IntPtr.Zero; - return obj; + return obj; } } @@ -493,22 +465,22 @@ public static unsafe ObjectReference FromAbi(IntPtr thisPtr, T vftblT) if (thisPtr == IntPtr.Zero) { return null; - } - + } + Marshal.AddRef(thisPtr); - if (ComWrappersSupport.IsFreeThreaded(thisPtr)) - { + if (ComWrappersSupport.IsFreeThreaded(thisPtr)) + { var obj = new ObjectReference(thisPtr, vftblT); - return obj; + return obj; } - else - { + else + { var obj = new ObjectReferenceWithContext( thisPtr, vftblT, Context.GetContextCallback(), Context.GetContextToken()); - return obj; + return obj; } } @@ -517,23 +489,23 @@ public static unsafe ObjectReference FromAbi(IntPtr thisPtr, T vftblT, Guid i if (thisPtr == IntPtr.Zero) { return null; - } - + } + Marshal.AddRef(thisPtr); - if (ComWrappersSupport.IsFreeThreaded(thisPtr)) - { + if (ComWrappersSupport.IsFreeThreaded(thisPtr)) + { var obj = new ObjectReference(thisPtr, vftblT); - return obj; + return obj; } - else - { + else + { var obj = new ObjectReferenceWithContext( thisPtr, vftblT, Context.GetContextCallback(), Context.GetContextToken(), iid); - return obj; + return obj; } } @@ -587,38 +559,38 @@ private protected virtual T GetVftblForCurrentContext() return _vftbl; } - internal static int TryAs(IObjectReference sourceRef, Guid iid, out ObjectReference objRef) - { - objRef = null; - - int hr = Marshal.QueryInterface(sourceRef.ThisPtr, ref iid, out IntPtr thatPtr); - - if (hr >= 0) - { - if (sourceRef.IsAggregated) - { - Marshal.Release(thatPtr); - } - - sourceRef.AddRefFromTrackerSource(); - - objRef = ObjectReference.Attach(ref thatPtr); - objRef.IsAggregated = sourceRef.IsAggregated; - objRef.PreventReleaseOnDispose = sourceRef.IsAggregated; - objRef.ReferenceTrackerPtr = sourceRef.ReferenceTrackerPtr; - } - - return hr; + internal static int TryAs(IObjectReference sourceRef, Guid iid, out ObjectReference objRef) + { + objRef = null; + + int hr = Marshal.QueryInterface(sourceRef.ThisPtr, ref iid, out IntPtr thatPtr); + + if (hr >= 0) + { + if (sourceRef.IsAggregated) + { + Marshal.Release(thatPtr); + } + + sourceRef.AddRefFromTrackerSource(); + + objRef = ObjectReference.Attach(ref thatPtr); + objRef.IsAggregated = sourceRef.IsAggregated; + objRef.PreventReleaseOnDispose = sourceRef.IsAggregated; + objRef.ReferenceTrackerPtr = sourceRef.ReferenceTrackerPtr; + } + + return hr; } } - internal sealed class ObjectReferenceWithContext< + internal sealed class ObjectReferenceWithContext< #if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] #endif T> : ObjectReference, IObjectReferenceWithContext { - private readonly IntPtr _contextCallbackPtr; + private readonly IntPtr _contextCallbackPtr; private readonly IntPtr _contextToken; private volatile ConcurrentDictionary __cachedContext; @@ -634,7 +606,7 @@ private ConcurrentDictionary Make_CachedContext() private volatile AgileReference __agileReference; private AgileReference AgileReference => _isAgileReferenceSet ? __agileReference : Make_AgileReference(); private AgileReference Make_AgileReference() - { + { Context.CallInContext(_contextCallbackPtr, _contextToken, InitAgileReference, null); // Set after CallInContext callback given callback can fail to occur. @@ -652,23 +624,23 @@ void InitAgileReference() internal ObjectReferenceWithContext(IntPtr thisPtr, IntPtr contextCallbackPtr, IntPtr contextToken) : base(thisPtr) { - _contextCallbackPtr = contextCallbackPtr; + _contextCallbackPtr = contextCallbackPtr; _contextToken = contextToken; - } - + } + internal ObjectReferenceWithContext(IntPtr thisPtr, IntPtr contextCallbackPtr, IntPtr contextToken, Guid iid) : this(thisPtr, contextCallbackPtr, contextToken) { _iid = iid; - } - + } + internal ObjectReferenceWithContext(IntPtr thisPtr, T vftblT, IntPtr contextCallbackPtr, IntPtr contextToken) : base(thisPtr, vftblT) { - _contextCallbackPtr = contextCallbackPtr; + _contextCallbackPtr = contextCallbackPtr; _contextToken = contextToken; - } - + } + internal ObjectReferenceWithContext(IntPtr thisPtr, T vftblT, IntPtr contextCallbackPtr, IntPtr contextToken, Guid iid) : this(thisPtr, vftblT, contextCallbackPtr, contextToken) { @@ -686,9 +658,9 @@ private protected override IntPtr GetThisPtrForCurrentContext() return cachedObjRef.ThisPtr; } - private protected override IntPtr GetContextToken() - { - return this._contextToken; + private protected override IntPtr GetContextToken() + { + return this._contextToken; } private protected override T GetVftblForCurrentContext() @@ -775,35 +747,35 @@ public override ObjectReference AsKnownPtr(IntPtr ptr) return objRef; } - internal static new int TryAs(IObjectReference sourceRef, Guid iid, out ObjectReference objRef) - { - objRef = null; - - int hr = Marshal.QueryInterface(sourceRef.ThisPtr, ref iid, out IntPtr thatPtr); - - if (hr >= 0) - { - if (sourceRef.IsAggregated) - { - Marshal.Release(thatPtr); - } - - sourceRef.AddRefFromTrackerSource(); - - objRef = new ObjectReferenceWithContext(thatPtr, Context.GetContextCallback(), Context.GetContextToken(), iid) - { - IsAggregated = sourceRef.IsAggregated, - PreventReleaseOnDispose = sourceRef.IsAggregated, - ReferenceTrackerPtr = sourceRef.ReferenceTrackerPtr - }; - } - - return hr; + internal static new int TryAs(IObjectReference sourceRef, Guid iid, out ObjectReference objRef) + { + objRef = null; + + int hr = Marshal.QueryInterface(sourceRef.ThisPtr, ref iid, out IntPtr thatPtr); + + if (hr >= 0) + { + if (sourceRef.IsAggregated) + { + Marshal.Release(thatPtr); + } + + sourceRef.AddRefFromTrackerSource(); + + objRef = new ObjectReferenceWithContext(thatPtr, Context.GetContextCallback(), Context.GetContextToken(), iid) + { + IsAggregated = sourceRef.IsAggregated, + PreventReleaseOnDispose = sourceRef.IsAggregated, + ReferenceTrackerPtr = sourceRef.ReferenceTrackerPtr + }; + } + + return hr; } } - internal interface IObjectReferenceWithContext - { + internal interface IObjectReferenceWithContext + { } #if EMBED