Skip to content

Commit

Permalink
Ensure the FactoryObjectReference also holds a pointer to the context…
Browse files Browse the repository at this point in the history
… callback. (#1492)
  • Loading branch information
jlaanstra authored Feb 2, 2024
1 parent 70e9541 commit ef21429
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
15 changes: 0 additions & 15 deletions src/WinRT.Runtime/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,8 @@ namespace WinRT
{
static partial class Context
{
[DllImport("api-ms-win-core-com-l1-1-0.dll")]
private static extern int CoGetObjectContext(ref Guid riid, out IntPtr ppv);

private static readonly Guid IID_ICallbackWithNoReentrancyToApplicationSTA = new(0x0A299774, 0x3E4E, 0xFC42, 0x1D, 0x9D, 0x72, 0xCE, 0xE1, 0x05, 0xCA, 0x57);

public static IntPtr GetContextCallback()
{
Guid riid = ABI.WinRT.Interop.IContextCallback.IID;
Marshal.ThrowExceptionForHR(CoGetObjectContext(ref riid, out IntPtr contextCallbackPtr));
return contextCallbackPtr;
}

// Calls the given callback in the right context.
// On any exception, calls onFail callback if any set.
// If not set, exception is handled due to today we don't
Expand Down Expand Up @@ -50,10 +40,5 @@ public unsafe static void CallInContext(IntPtr contextCallbackPtr, IntPtr contex
onFailCallback?.Invoke();
}
}

public static void DisposeContextCallback(IntPtr contextCallbackPtr)
{
MarshalInspectable<object>.DisposeAbi(contextCallbackPtr);
}
}
}
29 changes: 28 additions & 1 deletion src/cswinrt/strings/WinRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,30 @@ internal static partial class Context
[DllImport("api-ms-win-core-com-l1-1-0.dll")]
private static extern unsafe int CoGetContextToken(IntPtr* contextToken);

[DllImport("api-ms-win-core-com-l1-1-0.dll")]
private static extern int CoGetObjectContext(ref Guid riid, out IntPtr ppv);

public unsafe static IntPtr GetContextToken()
{
IntPtr contextToken;
Marshal.ThrowExceptionForHR(CoGetContextToken(&contextToken));
return contextToken;
}

public static IntPtr GetContextCallback()
{
Guid riid = InterfaceIIDs.IContextCallback_IID;
Marshal.ThrowExceptionForHR(CoGetObjectContext(ref riid, out IntPtr contextCallbackPtr));
return contextCallbackPtr;
}

public static void DisposeContextCallback(IntPtr contextCallbackPtr)
{
if (contextCallbackPtr != IntPtr.Zero)
{
MarshalInspectable<object>.DisposeAbi(contextCallbackPtr);
}
}
}

internal unsafe sealed class DllModule
Expand Down Expand Up @@ -459,7 +477,8 @@ internal sealed class FactoryObjectReference<
#endif
T> : IObjectReference
{
private readonly IntPtr _contextToken;
private readonly IntPtr _contextToken;
private readonly IntPtr _contextCallback;

public static FactoryObjectReference<T> Attach(ref IntPtr thisPtr)
{
Expand All @@ -478,6 +497,7 @@ internal FactoryObjectReference(IntPtr thisPtr) :
if (!IsFreeThreaded(this))
{
_contextToken = Context.GetContextToken();
_contextCallback = Context.GetContextCallback();
}
}

Expand All @@ -498,6 +518,13 @@ public static unsafe FactoryObjectReference<T> FromAbi(IntPtr thisPtr)
return obj;
}

protected override unsafe void Release()
{
base.Release();

Context.DisposeContextCallback(_contextCallback);
}

public bool IsObjectInContext()
{
return _contextToken == IntPtr.Zero || _contextToken == Context.GetContextToken();
Expand Down

0 comments on commit ef21429

Please sign in to comment.