From 5d4d1875f3bdaf2edea806cd0b0f60bcfe69e00e Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Wed, 28 Jun 2017 15:38:13 -0700 Subject: Support DispatcherQueues when getting WinRT sync context. --- src/vm/synchronizationcontextnative.cpp | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/vm/synchronizationcontextnative.cpp') diff --git a/src/vm/synchronizationcontextnative.cpp b/src/vm/synchronizationcontextnative.cpp index ac67f39349..03b289fc95 100644 --- a/src/vm/synchronizationcontextnative.cpp +++ b/src/vm/synchronizationcontextnative.cpp @@ -17,6 +17,7 @@ #ifdef FEATURE_APPX #include #include +#include "winrtdispatcherqueue.h" #endif #include "synchronizationcontextnative.h" @@ -133,6 +134,46 @@ void* QCALLTYPE SynchronizationContextNative::GetWinRTDispatcherForCurrentThread } } + // If we didn't find a CoreDispatcher for the thread, let's see if we can get a DispatcherQueue. + if (result == NULL) + { + SafeComHolderPreemp pDispatcherQueueStatics; + { + HRESULT hr = clr::winrt::GetActivationFactory(RuntimeClass_Windows_System_DispatcherQueue, + (Windows::System::IDispatcherQueueStatics**)pDispatcherQueueStatics.GetAddr()); + + // This interface was added in RS3 along with the public DispatcherQueue support. Older + // Windows builds don't support it and will return one of two HRESULTs from the call + // to GetActivationFactory above: + // - Pre-RS2 will return REGDB_E_CLASSNOTREG since Windows.System.DispatcherQueue + // does not exist at all. + // - RS2 will return E_NOINTERFACE since Windows.System.DispatcherQueue does exist + // in a limited fashion, but does not support the interface ID that we want. + // + // We should just return null if we see these two HRESULTs rather than throwing. + if (hr != REGDB_E_CLASSNOTREG && hr != E_NOINTERFACE) + { + IfFailThrow(hr); + } + } + + if (pDispatcherQueueStatics != NULL) + { + // + // Get the current IDispatcherQueue + // + SafeComHolderPreemp pDispatcherQueue; + + pDispatcherQueueStatics->GetForCurrentThread(&pDispatcherQueue); + + if (pDispatcherQueue != NULL) + { + pDispatcherQueue.SuppressRelease(); + result = (void*)pDispatcherQueue; + } + } + } + END_QCALL; return result; } -- cgit v1.2.3