summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorAditya Mandaleeka <adityam@microsoft.com>2017-06-28 15:38:13 -0700
committerAditya Mandaleeka <adityam@microsoft.com>2017-06-28 15:38:13 -0700
commit5d4d1875f3bdaf2edea806cd0b0f60bcfe69e00e (patch)
tree951f801f6a7eea3f0369eb96cd3e20597e50ef0e /src/vm
parent69afbba312e00845cc1440f0e1be2f04a41be841 (diff)
downloadcoreclr-5d4d1875f3bdaf2edea806cd0b0f60bcfe69e00e.tar.gz
coreclr-5d4d1875f3bdaf2edea806cd0b0f60bcfe69e00e.tar.bz2
coreclr-5d4d1875f3bdaf2edea806cd0b0f60bcfe69e00e.zip
Support DispatcherQueues when getting WinRT sync context.
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/synchronizationcontextnative.cpp41
-rw-r--r--src/vm/winrtdispatcherqueue.h103
2 files changed, 144 insertions, 0 deletions
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 <roapi.h>
#include <windows.ui.core.h>
+#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<Windows::System::IDispatcherQueueStatics> 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<Windows::System::IDispatcherQueue> pDispatcherQueue;
+
+ pDispatcherQueueStatics->GetForCurrentThread(&pDispatcherQueue);
+
+ if (pDispatcherQueue != NULL)
+ {
+ pDispatcherQueue.SuppressRelease();
+ result = (void*)pDispatcherQueue;
+ }
+ }
+ }
+
END_QCALL;
return result;
}
diff --git a/src/vm/winrtdispatcherqueue.h b/src/vm/winrtdispatcherqueue.h
new file mode 100644
index 0000000000..14f261da2b
--- /dev/null
+++ b/src/vm/winrtdispatcherqueue.h
@@ -0,0 +1,103 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+/*============================================================
+**
+** Header: winrtdispatcherqueue.h
+**
+===========================================================*/
+
+#ifndef _WINRTDISPATCHERQUEUE_H
+#define _WINRTDISPATCHERQUEUE_H
+
+#include <inspectable.h>
+
+// The following definitions were taken from windows.system.h.
+// Use windows.system.h from the RS3 SDK instead of this when that SDK is available.
+namespace Windows {
+ namespace System {
+ /* [v1_enum] */
+ enum DispatcherQueuePriority
+ {
+ DispatcherQueuePriority_Low = -10,
+ DispatcherQueuePriority_Normal = 0,
+ DispatcherQueuePriority_High = 10
+ } ;
+
+ MIDL_INTERFACE("DFA2DC9C-1A2D-4917-98F2-939AF1D6E0C8")
+ IDispatcherQueueHandler : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE Invoke( void) = 0;
+ };
+
+ MIDL_INTERFACE("5FEABB1D-A31C-4727-B1AC-37454649D56A")
+ IDispatcherQueueTimer : public IInspectable
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE Start( void) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE Stop( void) = 0;
+
+ virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_Interval(
+ /* [out][retval] */ __RPC__out ABI::Windows::Foundation::TimeSpan *value) = 0;
+
+ virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_Interval(
+ /* [in] */ ABI::Windows::Foundation::TimeSpan value) = 0;
+
+ virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_IsStarted(
+ /* [out][retval] */ __RPC__out boolean *value) = 0;
+
+ virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_IsRepeating(
+ /* [out][retval] */ __RPC__out boolean *value) = 0;
+
+ virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_IsRepeating(
+ /* [in] */ boolean value) = 0;
+
+#if 0 // We don't use these functions
+ virtual HRESULT STDMETHODCALLTYPE add_Tick(
+ /* [in] */ __RPC__in_opt __FITypedEventHandler_2_Windows__CSystem__CDispatcherQueueTimer_IInspectable *handler,
+ /* [out][retval] */ __RPC__out EventRegistrationToken *token) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Tick(
+ /* [in] */ EventRegistrationToken token) = 0;
+#endif
+ };
+
+ MIDL_INTERFACE("603E88E4-A338-4FFE-A457-A5CFB9CEB899")
+ IDispatcherQueue : public IInspectable
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE CreateTimer(
+ /* [out][retval] */ __RPC__deref_out_opt Windows::System::IDispatcherQueueTimer **result) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE TryEnqueue(
+ /* [in] */ __RPC__in_opt Windows::System::IDispatcherQueueHandler *callback,
+ /* [out][retval] */ __RPC__out boolean *result) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE TryEnqueueWithPriority(
+ /* [in] */ Windows::System::DispatcherQueuePriority priority,
+ /* [in] */ __RPC__in_opt Windows::System::IDispatcherQueueHandler *callback,
+ /* [out][retval] */ __RPC__out boolean *result) = 0;
+ };
+
+ MIDL_INTERFACE("A96D83D7-9371-4517-9245-D0824AC12C74")
+ IDispatcherQueueStatics : public IInspectable
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetForCurrentThread(
+ /* [out][retval] */ __RPC__deref_out_opt Windows::System::IDispatcherQueue **result) = 0;
+ };
+
+ extern const __declspec(selectany) IID & IID_IDispatcherQueueStatics = __uuidof(IDispatcherQueueStatics);
+ }
+}
+
+#ifndef RUNTIMECLASS_Windows_System_DispatcherQueue_DEFINED
+#define RUNTIMECLASS_Windows_System_DispatcherQueue_DEFINED
+ extern const __declspec(selectany) _Null_terminated_ WCHAR RuntimeClass_Windows_System_DispatcherQueue[] = L"Windows.System.DispatcherQueue";
+#endif
+
+#endif // _WINRTDISPATCHERQUEUE_H