Nikolay Sivov : mfplat: Add support for work item priority.

Alexandre Julliard julliard at winehq.org
Wed Mar 13 18:10:51 CDT 2019


Module: wine
Branch: master
Commit: e3b048c16230f4a71d65ab947f35bdb0d54cefa6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e3b048c16230f4a71d65ab947f35bdb0d54cefa6

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Mar 13 09:29:33 2019 +0300

mfplat: Add support for work item priority.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mfplat/mfplat.spec |  2 ++
 dlls/mfplat/queue.c     | 92 +++++++++++++++++++++++++++++++++++++++----------
 include/mfapi.h         |  2 ++
 3 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index c47af72..be5d8b2 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -123,7 +123,9 @@
 @ stdcall MFLockWorkQueue(long)
 @ stdcall MFPutWaitingWorkItem(long long ptr ptr)
 @ stdcall MFPutWorkItem(long ptr ptr)
+@ stdcall MFPutWorkItem2(long long ptr ptr)
 @ stdcall MFPutWorkItemEx(long ptr)
+@ stdcall MFPutWorkItemEx2(long long ptr)
 @ stub MFRecordError
 @ stdcall MFRemovePeriodicCallback(long)
 @ stdcall MFScheduleWorkItem(ptr ptr int64 ptr)
diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c
index e579168..c2cc623 100644
--- a/dlls/mfplat/queue.c
+++ b/dlls/mfplat/queue.c
@@ -59,10 +59,17 @@ struct work_item
     } u;
 };
 
+static const TP_CALLBACK_PRIORITY priorities[] =
+{
+    TP_CALLBACK_PRIORITY_HIGH,
+    TP_CALLBACK_PRIORITY_NORMAL,
+    TP_CALLBACK_PRIORITY_LOW,
+};
+
 struct queue
 {
     TP_POOL *pool;
-    TP_CALLBACK_ENVIRON_V3 env;
+    TP_CALLBACK_ENVIRON_V3 envs[ARRAY_SIZE(priorities)];
     CRITICAL_SECTION cs;
     struct list pending_items;
 };
@@ -160,16 +167,23 @@ static void release_work_item(struct work_item *item)
 
 static void init_work_queue(MFASYNC_WORKQUEUE_TYPE queue_type, struct queue *queue)
 {
-    unsigned int max_thread;
+    TP_CALLBACK_ENVIRON_V3 env;
+    unsigned int max_thread, i;
 
     queue->pool = CreateThreadpool(NULL);
-    memset(&queue->env, 0, sizeof(queue->env));
-    queue->env.Version = 3;
-    queue->env.Size = sizeof(queue->env);
-    queue->env.Pool = queue->pool;
-    queue->env.CleanupGroup = CreateThreadpoolCleanupGroup();
-    queue->env.CleanupGroupCancelCallback = standard_queue_cleanup_callback;
-    queue->env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL;
+
+    memset(&env, 0, sizeof(env));
+    env.Version = 3;
+    env.Size = sizeof(env);
+    env.Pool = queue->pool;
+    env.CleanupGroup = CreateThreadpoolCleanupGroup();
+    env.CleanupGroupCancelCallback = standard_queue_cleanup_callback;
+    env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL;
+    for (i = 0; i < ARRAY_SIZE(queue->envs); ++i)
+    {
+        queue->envs[i] = env;
+        queue->envs[i].CallbackPriority = priorities[i];
+    }
     list_init(&queue->pending_items);
     InitializeCriticalSection(&queue->cs);
 
@@ -267,7 +281,7 @@ static void shutdown_queue(struct queue *queue)
     if (!queue->pool)
         return;
 
-    CloseThreadpoolCleanupGroupMembers(queue->env.CleanupGroup, TRUE, NULL);
+    CloseThreadpoolCleanupGroupMembers(queue->envs[0].CleanupGroup, TRUE, NULL);
     CloseThreadpool(queue->pool);
     queue->pool = NULL;
 
@@ -339,15 +353,23 @@ static void CALLBACK standard_queue_worker(TP_CALLBACK_INSTANCE *instance, void
     release_work_item(item);
 }
 
-static HRESULT queue_submit_item(struct queue *queue, IMFAsyncResult *result)
+static HRESULT queue_submit_item(struct queue *queue, LONG priority, IMFAsyncResult *result)
 {
+    TP_CALLBACK_PRIORITY callback_priority;
     struct work_item *item;
     TP_WORK *work_object;
 
     if (!(item = alloc_work_item(queue, result)))
         return E_OUTOFMEMORY;
 
-    work_object = CreateThreadpoolWork(standard_queue_worker, item, (TP_CALLBACK_ENVIRON *)&queue->env);
+    if (priority == 0)
+        callback_priority = TP_CALLBACK_PRIORITY_NORMAL;
+    else if (priority < 0)
+        callback_priority = TP_CALLBACK_PRIORITY_LOW;
+    else
+        callback_priority = TP_CALLBACK_PRIORITY_HIGH;
+    work_object = CreateThreadpoolWork(standard_queue_worker, item,
+            (TP_CALLBACK_ENVIRON *)&queue->envs[callback_priority]);
     SubmitThreadpoolWork(work_object);
 
     TRACE("dispatched %p.\n", result);
@@ -355,7 +377,7 @@ static HRESULT queue_submit_item(struct queue *queue, IMFAsyncResult *result)
     return S_OK;
 }
 
-static HRESULT queue_put_work_item(DWORD queue_id, IMFAsyncResult *result)
+static HRESULT queue_put_work_item(DWORD queue_id, LONG priority, IMFAsyncResult *result)
 {
     struct queue *queue;
     HRESULT hr;
@@ -363,7 +385,7 @@ static HRESULT queue_put_work_item(DWORD queue_id, IMFAsyncResult *result)
     if (FAILED(hr = grab_queue(queue_id, &queue)))
         return hr;
 
-    hr = queue_submit_item(queue, result);
+    hr = queue_submit_item(queue, priority, result);
 
     return hr;
 }
@@ -380,7 +402,7 @@ static HRESULT invoke_async_callback(IMFAsyncResult *result)
     if (FAILED(lock_user_queue(queue)))
         queue = MFASYNC_CALLBACK_QUEUE_STANDARD;
 
-    hr = queue_put_work_item(queue, result);
+    hr = queue_put_work_item(queue, 0, result);
 
     unlock_user_queue(queue);
 
@@ -486,7 +508,8 @@ static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priorit
     else
         callback = waiting_item_callback;
 
-    item->u.wait_object = CreateThreadpoolWait(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env);
+    item->u.wait_object = CreateThreadpoolWait(callback, item,
+            (TP_CALLBACK_ENVIRON *)&queue->envs[TP_CALLBACK_PRIORITY_NORMAL]);
     SetThreadpoolWait(item->u.wait_object, event, NULL);
 
     TRACE("dispatched %p.\n", result);
@@ -519,7 +542,8 @@ static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, I
     filetime.dwLowDateTime = t.u.LowPart;
     filetime.dwHighDateTime = t.u.HighPart;
 
-    item->u.timer_object = CreateThreadpoolTimer(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env);
+    item->u.timer_object = CreateThreadpoolTimer(callback, item,
+            (TP_CALLBACK_ENVIRON *)&queue->envs[TP_CALLBACK_PRIORITY_NORMAL]);
     SetThreadpoolTimer(item->u.timer_object, &filetime, period, 0);
 
     TRACE("dispatched %p.\n", result);
@@ -828,7 +852,27 @@ HRESULT WINAPI MFPutWorkItem(DWORD queue, IMFAsyncCallback *callback, IUnknown *
     if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result)))
         return hr;
 
-    hr = queue_put_work_item(queue, result);
+    hr = queue_put_work_item(queue, 0, result);
+
+    IMFAsyncResult_Release(result);
+
+    return hr;
+}
+
+/***********************************************************************
+ *      MFPutWorkItem2 (mfplat.@)
+ */
+HRESULT WINAPI MFPutWorkItem2(DWORD queue, LONG priority, IMFAsyncCallback *callback, IUnknown *state)
+{
+    IMFAsyncResult *result;
+    HRESULT hr;
+
+    TRACE("%#x, %d, %p, %p.\n", queue, priority, callback, state);
+
+    if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result)))
+        return hr;
+
+    hr = queue_put_work_item(queue, priority, result);
 
     IMFAsyncResult_Release(result);
 
@@ -842,7 +886,17 @@ HRESULT WINAPI MFPutWorkItemEx(DWORD queue, IMFAsyncResult *result)
 {
     TRACE("%#x, %p\n", queue, result);
 
-    return queue_put_work_item(queue, result);
+    return queue_put_work_item(queue, 0, result);
+}
+
+/***********************************************************************
+ *      MFPutWorkItemEx2 (mfplat.@)
+ */
+HRESULT WINAPI MFPutWorkItemEx2(DWORD queue, LONG priority, IMFAsyncResult *result)
+{
+    TRACE("%#x, %d, %p\n", queue, priority, result);
+
+    return queue_put_work_item(queue, priority, result);
 }
 
 /***********************************************************************
diff --git a/include/mfapi.h b/include/mfapi.h
index fd5fbeb..21876fe 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -173,7 +173,9 @@ HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_IN
 HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result);
 HRESULT WINAPI MFLockPlatform(void);
 HRESULT WINAPI MFPutWorkItem(DWORD queue, IMFAsyncCallback *callback, IUnknown *state);
+HRESULT WINAPI MFPutWorkItem2(DWORD queue, LONG priority, IMFAsyncCallback *callback, IUnknown *state);
 HRESULT WINAPI MFPutWorkItemEx(DWORD queue, IMFAsyncResult *result);
+HRESULT WINAPI MFPutWorkItemEx2(DWORD queue, LONG priority, IMFAsyncResult *result);
 HRESULT WINAPI MFScheduleWorkItem(IMFAsyncCallback *callback, IUnknown *state, INT64 timeout, MFWORKITEM_KEY *key);
 HRESULT WINAPI MFScheduleWorkItemEx(IMFAsyncResult *result, INT64 timeout, MFWORKITEM_KEY *key);
 HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags, UINT32 cinput,




More information about the wine-cvs mailing list