Nikolay Sivov : mfplat: Add support for scheduled items.

Alexandre Julliard julliard at winehq.org
Fri Mar 1 16:42:10 CST 2019


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Mar  1 11:03:13 2019 +0300

mfplat: Add support for scheduled items.

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

---

 dlls/mfplat/queue.c        | 70 ++++++++++++++++++++++++++++++++++++++++++++--
 dlls/mfplat/tests/mfplat.c |  6 +---
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c
index 1434645..c793caa 100644
--- a/dlls/mfplat/queue.c
+++ b/dlls/mfplat/queue.c
@@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 #define MAX_USER_QUEUE_HANDLES 124
 
 #define WAIT_ITEM_KEY_MASK      (0x82000000)
+#define SCHEDULED_ITEM_KEY_MASK (0x80000000)
 
 static LONG next_item_key;
 
@@ -53,6 +54,7 @@ struct work_item
     union
     {
         TP_WAIT *wait_object;
+        TP_TIMER *timer_object;
     } u;
 };
 
@@ -414,6 +416,30 @@ static void CALLBACK waiting_item_cancelable_callback(TP_CALLBACK_INSTANCE *inst
     release_work_item(item);
 }
 
+static void CALLBACK scheduled_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer)
+{
+    struct work_item *item = context;
+
+    TRACE("result object %p.\n", item->result);
+
+    invoke_async_callback(item->result);
+
+    release_work_item(item);
+}
+
+static void CALLBACK scheduled_item_cancelable_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer)
+{
+    struct work_item *item = context;
+
+    TRACE("result object %p.\n", item->result);
+
+    queue_release_pending_item(item);
+
+    invoke_async_callback(item->result);
+
+    release_work_item(item);
+}
+
 static void queue_mark_item_pending(DWORD mask, struct work_item *item, MFWORKITEM_KEY *key)
 {
     *key = generate_item_key(mask);
@@ -450,6 +476,36 @@ static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priorit
     return S_OK;
 }
 
+static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, INT64 timeout, MFWORKITEM_KEY *key)
+{
+    PTP_TIMER_CALLBACK callback;
+    struct work_item *item;
+    FILETIME filetime;
+    LARGE_INTEGER t;
+
+    if (!(item = alloc_work_item(queue, result)))
+        return E_OUTOFMEMORY;
+
+    if (key)
+    {
+        queue_mark_item_pending(SCHEDULED_ITEM_KEY_MASK, item, key);
+        callback = scheduled_item_cancelable_callback;
+    }
+    else
+        callback = scheduled_item_callback;
+
+    t.QuadPart = timeout * 1000 * 10;
+    filetime.dwLowDateTime = t.u.LowPart;
+    filetime.dwHighDateTime = t.u.HighPart;
+
+    item->u.timer_object = CreateThreadpoolTimer(callback, item, &queue->env);
+    SetThreadpoolTimer(item->u.timer_object, &filetime, 0, 0);
+
+    TRACE("dispatched %p.\n", result);
+
+    return S_OK;
+}
+
 static HRESULT queue_cancel_item(struct queue *queue, MFWORKITEM_KEY key)
 {
     HRESULT hr = MF_E_NOT_FOUND;
@@ -463,6 +519,8 @@ static HRESULT queue_cancel_item(struct queue *queue, MFWORKITEM_KEY key)
             key >>= 32;
             if ((key & WAIT_ITEM_KEY_MASK) == WAIT_ITEM_KEY_MASK)
                 CloseThreadpoolWait(item->u.wait_object);
+            else if ((key & SCHEDULED_ITEM_KEY_MASK) == SCHEDULED_ITEM_KEY_MASK)
+                CloseThreadpoolTimer(item->u.timer_object);
             else
                 WARN("Unknown item key mask %#x.\n", (DWORD)key);
             queue_release_pending_item(item);
@@ -771,9 +829,17 @@ HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result)
 
 static HRESULT schedule_work_item(IMFAsyncResult *result, INT64 timeout, MFWORKITEM_KEY *key)
 {
-    FIXME("%p, %s, %p.\n", result, wine_dbgstr_longlong(timeout), key);
+    struct queue *queue;
+    HRESULT hr;
+
+    if (FAILED(hr = grab_queue(MFASYNC_CALLBACK_QUEUE_TIMER, &queue)))
+        return hr;
+
+    TRACE("%p, %s, %p.\n", result, wine_dbgstr_longlong(timeout), key);
+
+    hr = queue_submit_timer(queue, result, timeout, key);
 
-    return E_NOTIMPL;
+    return hr;
 }
 
 /***********************************************************************
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 915af01..fa77929 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -1050,11 +1050,9 @@ static void test_scheduled_items(void)
     ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
 
     hr = MFScheduleWorkItem(&callback, NULL, -5000, &key);
-todo_wine
     ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
 
     hr = MFCancelWorkItem(key);
-todo_wine
     ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
 
     hr = MFCancelWorkItem(key);
@@ -1084,15 +1082,13 @@ todo_wine
     IMFAsyncResult_Release(result);
 
     hr = MFScheduleWorkItem(&callback, NULL, -5000, &key);
-todo_wine
     ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
 
     hr = MFCancelWorkItem(key);
-todo_wine
     ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
 
     hr = MFShutdown();
-    ok(hr == S_OK, "Failed to shutdown, hr %#x.\n", hr);
+    ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
 }
 
 static void test_serial_queue(void)




More information about the wine-cvs mailing list