[PATCH 3/3] winegstreamer: Make IWMReader state transitions asynchronous.

Rémi Bernon wine at gitlab.winehq.org
Wed Jul 6 12:14:22 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winegstreamer/wm_asyncreader.c | 196 +++++++++++++++++++---------
 dlls/wmvcore/tests/wmvcore.c        | 103 +++++----------
 2 files changed, 166 insertions(+), 133 deletions(-)

diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c
index 9d8c2be45cb..033cda18dc4 100644
--- a/dlls/winegstreamer/wm_asyncreader.c
+++ b/dlls/winegstreamer/wm_asyncreader.c
@@ -40,7 +40,12 @@ struct async_reader
     CRITICAL_SECTION stream_cs;
     CONDITION_VARIABLE stream_cv;
 
-    bool running;
+    enum async_reader_state
+    {
+        STATE_CLOSED = 1,
+        STATE_STOPPED = 2,
+        STATE_RUNNING = 3,
+    } state, next_state;
 
     bool user_clock;
     QWORD user_time;
@@ -54,20 +59,62 @@ static REFERENCE_TIME get_current_time(const struct async_reader *reader)
     return (time.QuadPart * 1000) / reader->clock_frequency.QuadPart * 10000;
 }
 
-static void open_stream(struct async_reader *reader, IWMReaderCallback *callback, void *context)
+static void execute_state_transition(struct async_reader *reader)
 {
     static const DWORD zero;
 
-    IWMReaderCallback_AddRef(reader->callback = callback);
-    reader->context = context;
-    IWMReaderCallback_OnStatus(callback, WMT_OPENED, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, context);
+    switch (MAKELONG(reader->state, reader->next_state))
+    {
+        case MAKELONG(STATE_CLOSED, STATE_CLOSED):
+            break;
+        case MAKELONG(STATE_CLOSED, STATE_STOPPED):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_OPENED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+        case MAKELONG(STATE_CLOSED, STATE_RUNNING):
+            break;
+
+        case MAKELONG(STATE_STOPPED, STATE_CLOSED):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_CLOSED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+        case MAKELONG(STATE_STOPPED, STATE_STOPPED):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_STOPPED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+        case MAKELONG(STATE_STOPPED, STATE_RUNNING):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_STARTED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+
+        case MAKELONG(STATE_RUNNING, STATE_RUNNING):
+            break;
+        case MAKELONG(STATE_RUNNING, STATE_CLOSED):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_CLOSED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+        case MAKELONG(STATE_RUNNING, STATE_STOPPED):
+            IWMReaderCallback_OnStatus(reader->callback, WMT_STOPPED, S_OK,
+                    WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+            break;
+    }
+
+    reader->state = reader->next_state;
+    reader->next_state = 0;
 }
 
-static DWORD WINAPI stream_thread(void *arg)
+static void request_state_transition(struct async_reader *reader, enum async_reader_state new_state)
+{
+    reader->next_state = new_state;
+    if (!reader->stream_thread)
+        execute_state_transition(reader);
+    else
+        WakeConditionVariable(&reader->stream_cv);
+}
+
+static void stream_thread_running(struct async_reader *reader, IWMReaderCallbackAdvanced *callback_advanced)
 {
-    struct async_reader *reader = arg;
     IWMReaderCallback *callback = reader->callback;
-    IWMReaderCallbackAdvanced *callback_advanced;
     REFERENCE_TIME start_time;
     struct wm_stream *stream;
     static const DWORD zero;
@@ -79,14 +126,7 @@ static DWORD WINAPI stream_thread(void *arg)
 
     start_time = get_current_time(reader);
 
-    EnterCriticalSection(&reader->stream_cs);
-
-    if (FAILED(hr = IWMReaderCallback_QueryInterface(callback,
-            &IID_IWMReaderCallbackAdvanced, (void **)&callback_advanced)))
-        callback_advanced = NULL;
-    TRACE("Querying for IWMReaderCallbackAdvanced returned %#lx.\n", hr);
-
-    while (reader->running)
+    while (reader->state == STATE_RUNNING)
     {
         hr = wm_reader_get_stream_sample(&reader->reader, callback_advanced, 0, &sample, &pts, &duration, &flags, &stream_number);
         if (hr != S_OK)
@@ -105,12 +145,12 @@ static DWORD WINAPI stream_thread(void *arg)
                 EnterCriticalSection(&reader->stream_cs);
             }
 
-            while (pts > reader->user_time && reader->running)
+            while (pts > reader->user_time && reader->state == STATE_RUNNING)
                 SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE);
         }
         else
         {
-            while (reader->running)
+            while (reader->state == STATE_RUNNING)
             {
                 REFERENCE_TIME current_time = get_current_time(reader);
 
@@ -122,7 +162,7 @@ static DWORD WINAPI stream_thread(void *arg)
             }
         }
 
-        if (reader->running)
+        if (reader->state == STATE_RUNNING)
         {
             LeaveCriticalSection(&reader->stream_cs);
             if (stream->read_compressed)
@@ -139,8 +179,6 @@ static DWORD WINAPI stream_thread(void *arg)
         INSSBuffer_Release(sample);
     }
 
-    LeaveCriticalSection(&reader->stream_cs);
-
     if (hr == NS_E_NO_MORE_SAMPLES)
     {
         IWMReaderCallback_OnStatus(callback, WMT_END_OF_STREAMING, S_OK,
@@ -163,22 +201,68 @@ static DWORD WINAPI stream_thread(void *arg)
     {
         ERR("Failed to get sample, hr %#lx.\n", hr);
     }
+}
+
+static DWORD WINAPI stream_thread(void *arg)
+{
+    struct async_reader *reader = arg;
+    IWMReaderCallback *callback = reader->callback;
+    IWMReaderCallbackAdvanced *callback_advanced;
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection(&reader->stream_cs);
+
+    if (FAILED(hr = IWMReaderCallback_QueryInterface(callback,
+            &IID_IWMReaderCallbackAdvanced, (void **)&callback_advanced)))
+        callback_advanced = NULL;
+    TRACE("Querying for IWMReaderCallbackAdvanced returned %#lx.\n", hr);
+
+    while (reader->state != STATE_CLOSED || reader->next_state)
+    {
+        execute_state_transition(reader);
+
+        if (reader->state == STATE_RUNNING)
+        {
+            stream_thread_running(reader, callback_advanced);
+            if (!reader->next_state)
+                reader->state = STATE_STOPPED;
+        }
+
+        while (reader->state != STATE_CLOSED && !reader->next_state)
+            SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE);
+    }
 
     if (callback_advanced)
         IWMReaderCallbackAdvanced_Release(callback_advanced);
 
+    LeaveCriticalSection(&reader->stream_cs);
+
     TRACE("Reader is stopping; exiting.\n");
     return 0;
 }
 
-static void stop_streaming(struct async_reader *reader)
+static HRESULT open_stream(struct async_reader *reader, IWMReaderCallback *callback, void *context)
+{
+    IWMReaderCallback_AddRef((reader->callback = callback));
+    reader->context = context;
+    reader->state = STATE_CLOSED;
+    reader->next_state = STATE_STOPPED;
+
+    if (!(reader->stream_thread = CreateThread(NULL, 0, stream_thread, reader, 0, NULL)))
+    {
+        IWMReaderCallback_Release(reader->callback);
+        reader->callback = NULL;
+        reader->context = NULL;
+        return E_OUTOFMEMORY;
+    }
+
+    return S_OK;
+}
+
+static void close_stream(struct async_reader *reader)
 {
     if (reader->stream_thread)
     {
-        EnterCriticalSection(&reader->stream_cs);
-        reader->running = false;
-        LeaveCriticalSection(&reader->stream_cs);
-        WakeConditionVariable(&reader->stream_cv);
         WaitForSingleObject(reader->stream_thread, INFINITE);
         CloseHandle(reader->stream_thread);
         reader->stream_thread = NULL;
@@ -229,8 +313,9 @@ static HRESULT WINAPI WMReader_Open(IWMReader *iface, const WCHAR *url,
         return E_UNEXPECTED;
     }
 
-    if (SUCCEEDED(hr = wm_reader_open_file(&reader->reader, url)))
-        open_stream(reader, callback, context);
+    if (SUCCEEDED(hr = wm_reader_open_file(&reader->reader, url))
+            && FAILED(hr = open_stream(reader, callback, context)))
+        wm_reader_close(&reader->reader);
 
     LeaveCriticalSection(&reader->reader.cs);
     return hr;
@@ -239,22 +324,21 @@ static HRESULT WINAPI WMReader_Open(IWMReader *iface, const WCHAR *url,
 static HRESULT WINAPI WMReader_Close(IWMReader *iface)
 {
     struct async_reader *reader = impl_from_IWMReader(iface);
-    static const DWORD zero;
     HRESULT hr;
 
     TRACE("reader %p.\n", reader);
 
     EnterCriticalSection(&reader->reader.cs);
 
-    stop_streaming(reader);
+    EnterCriticalSection(&reader->stream_cs);
+    request_state_transition(reader, STATE_CLOSED);
+    LeaveCriticalSection(&reader->stream_cs);
+
+    close_stream(reader);
 
     hr = wm_reader_close(&reader->reader);
     if (reader->callback)
-    {
-        IWMReaderCallback_OnStatus(reader->callback, WMT_CLOSED, S_OK,
-                WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
         IWMReaderCallback_Release(reader->callback);
-    }
     reader->callback = NULL;
 
     LeaveCriticalSection(&reader->reader.cs);
@@ -315,7 +399,6 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface,
         QWORD start, QWORD duration, float rate, void *context)
 {
     struct async_reader *reader = impl_from_IWMReader(iface);
-    static const DWORD zero;
 
     TRACE("reader %p, start %s, duration %s, rate %.8e, context %p.\n",
             reader, debugstr_time(start), debugstr_time(duration), rate, context);
@@ -332,24 +415,14 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface,
         return NS_E_INVALID_REQUEST;
     }
 
-    stop_streaming(reader);
-
-    IWMReaderCallback_OnStatus(reader->callback, WMT_STARTED, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, context);
-    reader->context = context;
-
+    EnterCriticalSection(&reader->stream_cs);
     wm_reader_seek(&reader->reader, start, duration);
-
-    reader->running = true;
+    reader->context = context;
     reader->user_time = 0;
-
-    if (!(reader->stream_thread = CreateThread(NULL, 0, stream_thread, reader, 0, NULL)))
-    {
-        LeaveCriticalSection(&reader->reader.cs);
-        return E_OUTOFMEMORY;
-    }
+    request_state_transition(reader, STATE_RUNNING);
+    LeaveCriticalSection(&reader->stream_cs);
 
     LeaveCriticalSection(&reader->reader.cs);
-    WakeConditionVariable(&reader->stream_cv);
 
     return S_OK;
 }
@@ -357,7 +430,6 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface,
 static HRESULT WINAPI WMReader_Stop(IWMReader *iface)
 {
     struct async_reader *reader = impl_from_IWMReader(iface);
-    static const DWORD zero;
 
     TRACE("reader %p.\n", reader);
 
@@ -370,9 +442,10 @@ static HRESULT WINAPI WMReader_Stop(IWMReader *iface)
         return E_UNEXPECTED;
     }
 
-    stop_streaming(reader);
-    IWMReaderCallback_OnStatus(reader->callback, WMT_STOPPED, S_OK,
-            WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
+    EnterCriticalSection(&reader->stream_cs);
+    request_state_transition(reader, STATE_STOPPED);
+    LeaveCriticalSection(&reader->stream_cs);
+
     LeaveCriticalSection(&reader->reader.cs);
     return S_OK;
 }
@@ -732,8 +805,9 @@ static HRESULT WINAPI WMReaderAdvanced2_OpenStream(IWMReaderAdvanced6 *iface,
         return E_UNEXPECTED;
     }
 
-    if (SUCCEEDED(hr = wm_reader_open_stream(&reader->reader, stream)))
-        open_stream(reader, callback, context);
+    if (SUCCEEDED(hr = wm_reader_open_stream(&reader->reader, stream))
+            && FAILED(hr = open_stream(reader, callback, context)))
+        wm_reader_close(&reader->reader);
 
     LeaveCriticalSection(&reader->reader.cs);
     return hr;
@@ -1588,11 +1662,13 @@ static void async_reader_destroy(struct wm_reader *iface)
 
     TRACE("reader %p.\n", reader);
 
-    if (reader->stream_thread)
-    {
-        WaitForSingleObject(reader->stream_thread, INFINITE);
-        CloseHandle(reader->stream_thread);
-    }
+    EnterCriticalSection(&reader->stream_cs);
+    reader->state = STATE_CLOSED;
+    reader->next_state = 0;
+    LeaveCriticalSection(&reader->stream_cs);
+    WakeConditionVariable(&reader->stream_cv);
+
+    close_stream(reader);
 
     reader->stream_cs.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&reader->stream_cs);
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c
index 987f5def75a..510b9d0bb5a 100644
--- a/dlls/wmvcore/tests/wmvcore.c
+++ b/dlls/wmvcore/tests/wmvcore.c
@@ -1496,7 +1496,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta
             ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value);
             ok(context == (void *)0xdeadbeef, "Got unexpected context %p.\n", context);
             ret = WaitForSingleObject(callback->expect_opened, 100);
-            todo_wine
             ok(!ret, "Wait timed out.\n");
             SetEvent(callback->got_opened);
             break;
@@ -1506,7 +1505,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta
             ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value);
             ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
             ret = WaitForSingleObject(callback->expect_started, 100);
-            todo_wine
             ok(!ret, "Wait timed out.\n");
             callback->got_end_of_streaming = callback->got_eof = callback->got_sample = 0;
             SetEvent(callback->got_started);
@@ -1518,7 +1516,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta
             ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value);
             ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
             ret = WaitForSingleObject(callback->expect_stopped, 100);
-            todo_wine
             ok(!ret, "Wait timed out.\n");
             SetEvent(callback->got_stopped);
             break;
@@ -1890,14 +1887,10 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
     hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback->got_started, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STARTED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback->expect_started);
-        ret = WaitForSingleObject(callback->got_started, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback->expect_started);
+    ret = WaitForSingleObject(callback->got_started, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
@@ -1911,14 +1904,10 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st
     hr = IWMReader_Stop(reader);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback->got_stopped, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STOPPED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback->expect_stopped);
-        ret = WaitForSingleObject(callback->got_stopped, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback->expect_stopped);
+    ret = WaitForSingleObject(callback->got_stopped, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     ok(!outstanding_buffers, "Got %ld outstanding buffers.\n", outstanding_buffers);
 }
@@ -2217,14 +2206,10 @@ static void test_async_reader_streaming(void)
     ok(stream.refcount > 1, "Got refcount %ld.\n", stream.refcount);
     ok(callback.refcount > 1, "Got refcount %ld.\n", callback.refcount);
     ret = WaitForSingleObject(callback.got_opened, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_OPENED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_opened);
-        ret = WaitForSingleObject(callback.got_opened, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_opened);
+    ret = WaitForSingleObject(callback.got_opened, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReaderAdvanced2_OpenStream(advanced, &stream.IStream_iface, &callback.IWMReaderCallback_iface, (void **)0xdeadbee0);
     ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
@@ -2251,14 +2236,10 @@ static void test_async_reader_streaming(void)
     hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback.got_started, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STARTED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_started);
-        ret = WaitForSingleObject(callback.got_started, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_started);
+    ret = WaitForSingleObject(callback.got_started, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     /* By default the reader will time itself, and attempt to deliver samples
      * according to their presentation time. Call DeliverTime with the file
@@ -2290,14 +2271,10 @@ static void test_async_reader_streaming(void)
     hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback.got_started, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STARTED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_started);
-        ret = WaitForSingleObject(callback.got_started, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_started);
+    ret = WaitForSingleObject(callback.got_started, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
@@ -2309,26 +2286,18 @@ static void test_async_reader_streaming(void)
     hr = IWMReader_Stop(reader);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback.got_stopped, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STOPPED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_stopped);
-        ret = WaitForSingleObject(callback.got_stopped, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_stopped);
+    ret = WaitForSingleObject(callback.got_stopped, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReader_Stop(reader);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback.got_stopped, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STOPPED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_stopped);
-        ret = WaitForSingleObject(callback.got_stopped, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_stopped);
+    ret = WaitForSingleObject(callback.got_stopped, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     test_reader_attributes(profile);
     test_async_reader_selection(reader, advanced, &callback);
@@ -2397,14 +2366,10 @@ static void test_async_reader_types(void)
     ok(stream.refcount > 1, "Got refcount %ld.\n", stream.refcount);
     ok(callback.refcount > 1, "Got refcount %ld.\n", callback.refcount);
     ret = WaitForSingleObject(callback.got_opened, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_OPENED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_opened);
-        ret = WaitForSingleObject(callback.got_opened, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_opened);
+    ret = WaitForSingleObject(callback.got_opened, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     for (i = 0; i < 2; ++i)
     {
@@ -2627,14 +2592,10 @@ static void test_async_reader_file(void)
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ok(callback.refcount > 1, "Got refcount %ld.\n", callback.refcount);
     ret = WaitForSingleObject(callback.got_opened, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_OPENED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_opened);
-        ret = WaitForSingleObject(callback.got_opened, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_opened);
+    ret = WaitForSingleObject(callback.got_opened, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReader_Open(reader, filename, &callback.IWMReaderCallback_iface, (void **)0xdeadbee0);
     ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
@@ -2647,14 +2608,10 @@ static void test_async_reader_file(void)
     hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
     ret = WaitForSingleObject(callback.got_started, 0);
-    todo_wine
     ok(ret == WAIT_TIMEOUT, "Got unexpected WMT_STARTED.\n");
-    if (ret == WAIT_TIMEOUT)
-    {
-        SetEvent(callback.expect_started);
-        ret = WaitForSingleObject(callback.got_started, 1000);
-        ok(!ret, "Wait timed out.\n");
-    }
+    SetEvent(callback.expect_started);
+    ret = WaitForSingleObject(callback.got_started, 1000);
+    ok(!ret, "Wait timed out.\n");
 
     hr = IWMReader_Close(reader);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/393



More information about the wine-devel mailing list