Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/systemclock.c | 258 +++++++++++++++++++------------------- 1 file changed, 128 insertions(+), 130 deletions(-)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index e9f13b5130..d95bd3ab3a 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -26,14 +26,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-typedef struct SystemClockAdviseEntry SystemClockAdviseEntry; -struct SystemClockAdviseEntry { - SystemClockAdviseEntry* next; - SystemClockAdviseEntry* prev; - - HANDLE hEvent; - REFERENCE_TIME rtBaseTime; - REFERENCE_TIME rtIntervalTime; +struct advise_sink +{ + struct list entry; + HANDLE hEvent; + REFERENCE_TIME rtBaseTime, rtIntervalTime; };
typedef struct SystemClockImpl { @@ -47,8 +44,8 @@ typedef struct SystemClockImpl { REFERENCE_TIME last_time; CRITICAL_SECTION safe;
- SystemClockAdviseEntry* pSingleShotAdvise; - SystemClockAdviseEntry* pPeriodicAdvise; + /* These lists are ordered by expiration time (soonest first). */ + struct list single_sinks, periodic_sinks; } SystemClockImpl;
static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface) @@ -56,34 +53,21 @@ static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface) return CONTAINING_RECORD(iface, SystemClockImpl, IReferenceClock_iface); }
+static void insert_advise_sink(struct advise_sink *sink, struct list *queue) +{ + REFERENCE_TIME due_time = sink->rtBaseTime + sink->rtIntervalTime; + struct advise_sink *cursor;
-static void QUARTZ_RemoveAviseEntryFromQueue(SystemClockImpl* This, SystemClockAdviseEntry* pEntry) { - if (pEntry->prev) pEntry->prev->next = pEntry->next; - if (pEntry->next) pEntry->next->prev = pEntry->prev; - if (This->pSingleShotAdvise == pEntry) This->pSingleShotAdvise = pEntry->next; - if (This->pPeriodicAdvise == pEntry) This->pPeriodicAdvise = pEntry->next; -} + LIST_FOR_EACH_ENTRY(cursor, queue, struct advise_sink, entry) + { + if (cursor->rtBaseTime + cursor->rtIntervalTime > due_time) + { + list_add_before(&cursor->entry, &sink->entry); + return; + } + }
-static void QUARTZ_InsertAviseEntryFromQueue(SystemClockImpl* This, SystemClockAdviseEntry* pEntry, SystemClockAdviseEntry** pQueue) { - SystemClockAdviseEntry* prev_it = NULL; - SystemClockAdviseEntry* it = NULL; - REFERENCE_TIME bornTime = pEntry->rtBaseTime + pEntry->rtIntervalTime; - - for (it = *pQueue; NULL != it && (it->rtBaseTime + it->rtIntervalTime) < bornTime; it = it->next) { - prev_it = it; - } - if (NULL == prev_it) { - pEntry->prev = NULL; - if (NULL != (*pQueue)) pEntry->next = (*pQueue)->next; - /*assert( NULL == pEntry->next->prev );*/ - if (NULL != pEntry->next) pEntry->next->prev = pEntry; - (*pQueue) = pEntry; - } else { - pEntry->prev = prev_it; - pEntry->next = prev_it->next; - prev_it->next = pEntry; - if (NULL != pEntry->next) pEntry->next->prev = pEntry; - } + list_add_tail(queue, &sink->entry); }
#define MAX_REFTIME (REFERENCE_TIME)(0x7FFFFFFFFFFFFFFF) @@ -94,12 +78,12 @@ static void QUARTZ_InsertAviseEntryFromQueue(SystemClockImpl* This, SystemClockA
static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { SystemClockImpl* This = lpParam; + struct advise_sink *sink, *cursor; + struct list *entry; DWORD timeOut = INFINITE; - DWORD tmpTimeOut; MSG msg; HRESULT hr; REFERENCE_TIME curTime; - SystemClockAdviseEntry* it = NULL;
TRACE("(%p): Main Loop\n", This);
@@ -115,31 +99,33 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { }
/** First SingleShots Advice: sorted list */ - it = This->pSingleShotAdvise; - while ((NULL != it) && (it->rtBaseTime + it->rtIntervalTime) <= curTime) { - SystemClockAdviseEntry* nextit = it->next; - /** send event ... */ - SetEvent(it->hEvent); - /** ... and Release it */ - QUARTZ_RemoveAviseEntryFromQueue(This, it); - heap_free(it); - it = nextit; + LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->single_sinks, struct advise_sink, entry) + { + if (sink->rtBaseTime + sink->rtIntervalTime > curTime) + break; + + SetEvent(sink->hEvent); + list_remove(&sink->entry); + heap_free(sink); + } + + if ((entry = list_head(&This->single_sinks))) + { + sink = LIST_ENTRY(entry, struct advise_sink, entry); + timeOut = (sink->rtBaseTime + sink->rtIntervalTime - curTime) / 10000; } - if (NULL != it) timeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000; else timeOut = INFINITE;
/** Now Periodics Advice: semi sorted list (sort cannot be used) */ - for (it = This->pPeriodicAdvise; NULL != it; it = it->next) { - if (it->rtBaseTime <= curTime) { - DWORD nPeriods = (DWORD) ((curTime - it->rtBaseTime) / it->rtIntervalTime); - /** Release the semaphore ... */ - ReleaseSemaphore(it->hEvent, nPeriods, NULL); - /** ... and refresh time */ - it->rtBaseTime += nPeriods * it->rtIntervalTime; - /*assert( it->rtBaseTime + it->rtIntervalTime < curTime );*/ + LIST_FOR_EACH_ENTRY(sink, &This->periodic_sinks, struct advise_sink, entry) + { + if (sink->rtBaseTime <= curTime) + { + DWORD periods = (curTime - sink->rtBaseTime) / sink->rtIntervalTime; + ReleaseSemaphore(sink->hEvent, periods, NULL); + sink->rtBaseTime += periods * sink->rtIntervalTime; } - tmpTimeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000; - if (timeOut > tmpTimeOut) timeOut = tmpTimeOut; + timeOut = min(timeOut, ((sink->rtBaseTime + sink->rtIntervalTime) - curTime) / 10000); }
outrefresh: @@ -263,101 +249,112 @@ static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock *iface, REFERENCE_ return hr; }
-static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock* iface, REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, HEVENT hEvent, DWORD_PTR* pdwAdviseCookie) { - SystemClockImpl *This = impl_from_IReferenceClock(iface); - SystemClockAdviseEntry* pEntry = NULL; +static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock *iface, + REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie) +{ + SystemClockImpl *clock = impl_from_IReferenceClock(iface); + struct advise_sink *sink;
- TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtBaseTime), - wine_dbgstr_longlong(rtStreamTime), hEvent, pdwAdviseCookie); + TRACE("clock %p, base %s, offset %s, event %#lx, cookie %p.\n", + clock, wine_dbgstr_longlong(base), wine_dbgstr_longlong(offset), event, cookie);
- if (!hEvent) { - return E_INVALIDARG; - } - if (0 >= rtBaseTime + rtStreamTime) { - return E_INVALIDARG; - } - if (NULL == pdwAdviseCookie) { - return E_POINTER; - } + if (!event) + return E_INVALIDARG;
- if (!(pEntry = heap_alloc_zero(sizeof(*pEntry)))) - return E_OUTOFMEMORY; + if (base + offset <= 0) + return E_INVALIDARG;
- pEntry->hEvent = (HANDLE) hEvent; - pEntry->rtBaseTime = rtBaseTime + rtStreamTime; - pEntry->rtIntervalTime = 0; + if (!cookie) + return E_POINTER;
- EnterCriticalSection(&This->safe); - QUARTZ_InsertAviseEntryFromQueue(This, pEntry, &This->pSingleShotAdvise); - LeaveCriticalSection(&This->safe); + if (!(sink = heap_alloc_zero(sizeof(*sink)))) + return E_OUTOFMEMORY;
- SystemClockPostMessageToAdviseThread(This, ADVISE_ADD_SINGLESHOT); + sink->hEvent = (HANDLE)event; + sink->rtBaseTime = base + offset; + sink->rtIntervalTime = 0;
- *pdwAdviseCookie = (DWORD_PTR) (pEntry); - return S_OK; + EnterCriticalSection(&clock->safe); + insert_advise_sink(sink, &clock->single_sinks); + LeaveCriticalSection(&clock->safe); + + SystemClockPostMessageToAdviseThread(clock, ADVISE_ADD_SINGLESHOT); + + *cookie = (DWORD_PTR)sink; + return S_OK; }
-static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, HSEMAPHORE hSemaphore, DWORD_PTR* pdwAdviseCookie) { - SystemClockImpl *This = impl_from_IReferenceClock(iface); - SystemClockAdviseEntry* pEntry = NULL; +static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, + REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie) +{ + SystemClockImpl *clock = impl_from_IReferenceClock(iface); + struct advise_sink *sink;
- TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtStartTime), - wine_dbgstr_longlong(rtPeriodTime), hSemaphore, pdwAdviseCookie); + TRACE("clock %p, start %s, period %s, semaphore %#lx, cookie %p.\n", + clock, wine_dbgstr_longlong(start), wine_dbgstr_longlong(period), semaphore, cookie);
- if (!hSemaphore) { - return E_INVALIDARG; - } - if (0 >= rtStartTime || 0 >= rtPeriodTime) { - return E_INVALIDARG; - } - if (NULL == pdwAdviseCookie) { - return E_POINTER; - } + if (!semaphore) + return E_INVALIDARG;
- if (!(pEntry = heap_alloc_zero(sizeof(*pEntry)))) - return E_OUTOFMEMORY; + if (start <= 0 || period <= 0) + return E_INVALIDARG;
- pEntry->hEvent = (HANDLE) hSemaphore; - pEntry->rtBaseTime = rtStartTime; - pEntry->rtIntervalTime = rtPeriodTime; + if (!cookie) + return E_POINTER;
- EnterCriticalSection(&This->safe); - QUARTZ_InsertAviseEntryFromQueue(This, pEntry, &This->pPeriodicAdvise); - LeaveCriticalSection(&This->safe); + if (!(sink = heap_alloc_zero(sizeof(*sink)))) + return E_OUTOFMEMORY;
- SystemClockPostMessageToAdviseThread(This, ADVISE_ADD_PERIODIC); + sink->hEvent = (HANDLE)semaphore; + sink->rtBaseTime = start; + sink->rtIntervalTime = period;
- *pdwAdviseCookie = (DWORD_PTR) (pEntry); - return S_OK; + EnterCriticalSection(&clock->safe); + insert_advise_sink(sink, &clock->periodic_sinks); + LeaveCriticalSection(&clock->safe); + + SystemClockPostMessageToAdviseThread(clock, ADVISE_ADD_PERIODIC); + + *cookie = (DWORD_PTR)sink; + return S_OK; }
-static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock* iface, DWORD_PTR dwAdviseCookie) { - SystemClockImpl *This = impl_from_IReferenceClock(iface); - SystemClockAdviseEntry* pEntry = NULL; - SystemClockAdviseEntry* it = NULL; - HRESULT ret = S_OK; - TRACE("(%p, %lu)\n", This, dwAdviseCookie); +static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR cookie) +{ + SystemClockImpl *clock = impl_from_IReferenceClock(iface); + struct advise_sink *sink;
- pEntry = (SystemClockAdviseEntry*) dwAdviseCookie; + TRACE("clock %p, cookie %#lx.\n", clock, cookie);
- EnterCriticalSection(&This->safe); - for (it = This->pPeriodicAdvise; NULL != it && it != pEntry; it = it->next) ; - if (it != pEntry) { - for (it = This->pSingleShotAdvise; NULL != it && it != pEntry; it = it->next) ; - if (it != pEntry) { - ret = S_FALSE; - goto out; + EnterCriticalSection(&clock->safe); + + LIST_FOR_EACH_ENTRY(sink, &clock->single_sinks, struct advise_sink, entry) + { + if (sink == (struct advise_sink *)cookie) + { + list_remove(&sink->entry); + heap_free(sink); + SystemClockPostMessageToAdviseThread(clock, ADVISE_REMOVE); + LeaveCriticalSection(&clock->safe); + return S_OK; + } } - }
- QUARTZ_RemoveAviseEntryFromQueue(This, pEntry); - heap_free(pEntry); + LIST_FOR_EACH_ENTRY(sink, &clock->periodic_sinks, struct advise_sink, entry) + { + if (sink == (struct advise_sink *)cookie) + { + list_remove(&sink->entry); + heap_free(sink); + SystemClockPostMessageToAdviseThread(clock, ADVISE_REMOVE); + LeaveCriticalSection(&clock->safe); + return S_OK; + } + }
- SystemClockPostMessageToAdviseThread(This, ADVISE_REMOVE); + LeaveCriticalSection(&clock->safe);
-out: - LeaveCriticalSection(&This->safe); - return ret; + return S_FALSE; }
static const IReferenceClockVtbl SystemClock_Vtbl = @@ -384,7 +381,8 @@ HRESULT QUARTZ_CreateSystemClock(IUnknown *outer, void **out) }
object->IReferenceClock_iface.lpVtbl = &SystemClock_Vtbl; - + list_init(&object->single_sinks); + list_init(&object->periodic_sinks); InitializeCriticalSection(&object->safe); object->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.safe");
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/systemclock.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index d95bd3ab3a..511abf66fb 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -82,7 +82,6 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { struct list *entry; DWORD timeOut = INFINITE; MSG msg; - HRESULT hr; REFERENCE_TIME curTime;
TRACE("(%p): Main Loop\n", This); @@ -91,12 +90,8 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { if (timeOut > 0) MsgWaitForMultipleObjects(0, NULL, FALSE, timeOut, QS_POSTMESSAGE|QS_SENDMESSAGE|QS_TIMER);
EnterCriticalSection(&This->safe); - /*timeOut = IReferenceClock_OnTimerUpdated(This); */ - hr = IReferenceClock_GetTime(&This->IReferenceClock_iface, &curTime); - if (FAILED(hr)) { - timeOut = INFINITE; - goto outrefresh; - } + + curTime = GetTickCount64() * 10000;
/** First SingleShots Advice: sorted list */ LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->single_sinks, struct advise_sink, entry) @@ -128,7 +123,6 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { timeOut = min(timeOut, ((sink->rtBaseTime + sink->rtIntervalTime) - curTime) / 10000); }
-outrefresh: LeaveCriticalSection(&This->safe);
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/systemclock.c | 127 +++++++++++++------------------------- 1 file changed, 43 insertions(+), 84 deletions(-)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index 511abf66fb..8291fe5fb2 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -34,18 +34,16 @@ struct advise_sink };
typedef struct SystemClockImpl { - IReferenceClock IReferenceClock_iface; - LONG ref; + IReferenceClock IReferenceClock_iface; + LONG ref;
- /** IReferenceClock */ - HANDLE adviseThread; - DWORD adviseThreadId; - BOOL adviseThreadActive; - REFERENCE_TIME last_time; - CRITICAL_SECTION safe; + BOOL thread_created; + HANDLE thread, notify_event, stop_event; + REFERENCE_TIME last_time; + CRITICAL_SECTION safe;
- /* These lists are ordered by expiration time (soonest first). */ - struct list single_sinks, periodic_sinks; + /* These lists are ordered by expiration time (soonest first). */ + struct list single_sinks, periodic_sinks; } SystemClockImpl;
static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface) @@ -70,25 +68,17 @@ static void insert_advise_sink(struct advise_sink *sink, struct list *queue) list_add_tail(queue, &sink->entry); }
-#define MAX_REFTIME (REFERENCE_TIME)(0x7FFFFFFFFFFFFFFF) -#define ADVISE_EXIT (WM_APP + 0) -#define ADVISE_REMOVE (WM_APP + 2) -#define ADVISE_ADD_SINGLESHOT (WM_APP + 4) -#define ADVISE_ADD_PERIODIC (WM_APP + 8) - static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { SystemClockImpl* This = lpParam; struct advise_sink *sink, *cursor; struct list *entry; DWORD timeOut = INFINITE; - MSG msg; REFERENCE_TIME curTime; + HANDLE handles[2] = {This->stop_event, This->notify_event};
TRACE("(%p): Main Loop\n", This);
while (TRUE) { - if (timeOut > 0) MsgWaitForMultipleObjects(0, NULL, FALSE, timeOut, QS_POSTMESSAGE|QS_SENDMESSAGE|QS_TIMER); - EnterCriticalSection(&This->safe);
curTime = GetTickCount64() * 10000; @@ -124,58 +114,21 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { }
LeaveCriticalSection(&This->safe); - - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { - /** if hwnd we suppose that is a windows event ... */ - if (NULL != msg.hwnd) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } else { - switch (msg.message) { - case WM_QUIT: - case ADVISE_EXIT: - goto outofthread; - case ADVISE_ADD_SINGLESHOT: - case ADVISE_ADD_PERIODIC: - /** set timeout to 0 to do a rescan now */ - timeOut = 0; - break; - case ADVISE_REMOVE: - /** hmmmm what we can do here ... */ - timeOut = INFINITE; - break; - default: - ERR("Unhandled message %u. Critical Path\n", msg.message); - break; - } - } - } - }
-outofthread: - TRACE("(%p): Exiting\n", This); - return 0; + if (WaitForMultipleObjects(2, handles, FALSE, timeOut) == 0) + return 0; + } } -/*static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { */
-static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMsg) { - if (FALSE == This->adviseThreadActive) { - BOOL res; - This->adviseThread = CreateThread(NULL, 0, SystemClockAdviseThread, This, 0, &This->adviseThreadId); - if (NULL == This->adviseThread) return FALSE; - SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL); - This->adviseThreadActive = TRUE; - while(1) { - res = PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0); - /* Let the thread creates its message queue (with MsgWaitForMultipleObjects call) by yielding and retrying */ - if (!res && (GetLastError() == ERROR_INVALID_THREAD_ID)) - Sleep(0); - else - break; +static void notify_thread(SystemClockImpl *clock) +{ + if (!InterlockedCompareExchange(&clock->thread_created, TRUE, FALSE)) + { + clock->thread = CreateThread(NULL, 0, SystemClockAdviseThread, clock, 0, NULL); + clock->notify_event = CreateEventW(NULL, FALSE, FALSE, NULL); + clock->stop_event = CreateEventW(NULL, TRUE, FALSE, NULL); } - return res; - } - return PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0); + SetEvent(clock->notify_event); }
static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock* iface) { @@ -203,20 +156,28 @@ static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock* iface, REF return E_NOINTERFACE; }
-static ULONG WINAPI SystemClockImpl_Release(IReferenceClock* iface) { - SystemClockImpl *This = impl_from_IReferenceClock(iface); - ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p): ReleaseRef to %d\n", This, ref); - if (ref == 0) { - if (This->adviseThreadActive && SystemClockPostMessageToAdviseThread(This, ADVISE_EXIT)) { - WaitForSingleObject(This->adviseThread, INFINITE); - CloseHandle(This->adviseThread); +static ULONG WINAPI SystemClockImpl_Release(IReferenceClock *iface) +{ + SystemClockImpl *clock = impl_from_IReferenceClock(iface); + ULONG refcount = InterlockedDecrement(&clock->ref); + + TRACE("%p decreasing refcount to %u.\n", clock, refcount); + + if (!refcount) + { + if (clock->thread) + { + SetEvent(clock->stop_event); + WaitForSingleObject(clock->thread, INFINITE); + CloseHandle(clock->thread); + CloseHandle(clock->notify_event); + CloseHandle(clock->stop_event); + } + clock->safe.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&clock->safe); + heap_free(clock); } - This->safe.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->safe); - heap_free(This); - } - return ref; + return refcount; }
static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock *iface, REFERENCE_TIME *time) @@ -272,7 +233,7 @@ static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock *iface, insert_advise_sink(sink, &clock->single_sinks); LeaveCriticalSection(&clock->safe);
- SystemClockPostMessageToAdviseThread(clock, ADVISE_ADD_SINGLESHOT); + notify_thread(clock);
*cookie = (DWORD_PTR)sink; return S_OK; @@ -307,7 +268,7 @@ static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, insert_advise_sink(sink, &clock->periodic_sinks); LeaveCriticalSection(&clock->safe);
- SystemClockPostMessageToAdviseThread(clock, ADVISE_ADD_PERIODIC); + notify_thread(clock);
*cookie = (DWORD_PTR)sink; return S_OK; @@ -328,7 +289,6 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR { list_remove(&sink->entry); heap_free(sink); - SystemClockPostMessageToAdviseThread(clock, ADVISE_REMOVE); LeaveCriticalSection(&clock->safe); return S_OK; } @@ -340,7 +300,6 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR { list_remove(&sink->entry); heap_free(sink); - SystemClockPostMessageToAdviseThread(clock, ADVISE_REMOVE); LeaveCriticalSection(&clock->safe); return S_OK; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=49391
Your paranoid android.
=== debian9 (64 bit WoW report) ===
quartz: filtergraph: Timeout systemclock: Timeout
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/systemclock.c | 4 ++-- dlls/quartz/tests/systemclock.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index 8291fe5fb2..c445f57ff7 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -106,11 +106,11 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { { if (sink->rtBaseTime <= curTime) { - DWORD periods = (curTime - sink->rtBaseTime) / sink->rtIntervalTime; + DWORD periods = ((curTime - sink->rtBaseTime) / sink->rtIntervalTime) + 1; ReleaseSemaphore(sink->hEvent, periods, NULL); sink->rtBaseTime += periods * sink->rtIntervalTime; } - timeOut = min(timeOut, ((sink->rtBaseTime + sink->rtIntervalTime) - curTime) / 10000); + timeOut = min(timeOut, (sink->rtBaseTime - curTime) / 10000); }
LeaveCriticalSection(&This->safe); diff --git a/dlls/quartz/tests/systemclock.c b/dlls/quartz/tests/systemclock.c index 77e6c63001..cd291e1490 100644 --- a/dlls/quartz/tests/systemclock.c +++ b/dlls/quartz/tests/systemclock.c @@ -160,7 +160,7 @@ static void test_advise(void)
hr = IReferenceClock_AdvisePeriodic(clock, current, 500 * 10000, (HSEMAPHORE)semaphore, &cookie); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(!WaitForSingleObject(semaphore, 10), "Semaphore should be signaled.\n"); + ok(!WaitForSingleObject(semaphore, 10), "Semaphore should be signaled.\n"); for (i = 0; i < 5; ++i) { ok(WaitForSingleObject(semaphore, 480) == WAIT_TIMEOUT, "Semaphore should not be signaled.\n");
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/systemclock.c | 70 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index c445f57ff7..0cc6d87f84 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -29,8 +29,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); struct advise_sink { struct list entry; - HANDLE hEvent; - REFERENCE_TIME rtBaseTime, rtIntervalTime; + HANDLE handle; + REFERENCE_TIME due_time, period; };
typedef struct SystemClockImpl { @@ -40,7 +40,7 @@ typedef struct SystemClockImpl { BOOL thread_created; HANDLE thread, notify_event, stop_event; REFERENCE_TIME last_time; - CRITICAL_SECTION safe; + CRITICAL_SECTION cs;
/* These lists are ordered by expiration time (soonest first). */ struct list single_sinks, periodic_sinks; @@ -53,12 +53,12 @@ static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface)
static void insert_advise_sink(struct advise_sink *sink, struct list *queue) { - REFERENCE_TIME due_time = sink->rtBaseTime + sink->rtIntervalTime; + REFERENCE_TIME due_time = sink->due_time + sink->period; struct advise_sink *cursor;
LIST_FOR_EACH_ENTRY(cursor, queue, struct advise_sink, entry) { - if (cursor->rtBaseTime + cursor->rtIntervalTime > due_time) + if (cursor->due_time + cursor->period > due_time) { list_add_before(&cursor->entry, &sink->entry); return; @@ -79,17 +79,17 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { TRACE("(%p): Main Loop\n", This);
while (TRUE) { - EnterCriticalSection(&This->safe); + EnterCriticalSection(&This->cs);
curTime = GetTickCount64() * 10000;
/** First SingleShots Advice: sorted list */ LIST_FOR_EACH_ENTRY_SAFE(sink, cursor, &This->single_sinks, struct advise_sink, entry) { - if (sink->rtBaseTime + sink->rtIntervalTime > curTime) + if (sink->due_time + sink->period > curTime) break;
- SetEvent(sink->hEvent); + SetEvent(sink->handle); list_remove(&sink->entry); heap_free(sink); } @@ -97,23 +97,23 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { if ((entry = list_head(&This->single_sinks))) { sink = LIST_ENTRY(entry, struct advise_sink, entry); - timeOut = (sink->rtBaseTime + sink->rtIntervalTime - curTime) / 10000; + timeOut = (sink->due_time + sink->period - curTime) / 10000; } else timeOut = INFINITE;
/** Now Periodics Advice: semi sorted list (sort cannot be used) */ LIST_FOR_EACH_ENTRY(sink, &This->periodic_sinks, struct advise_sink, entry) { - if (sink->rtBaseTime <= curTime) + if (sink->due_time <= curTime) { - DWORD periods = ((curTime - sink->rtBaseTime) / sink->rtIntervalTime) + 1; - ReleaseSemaphore(sink->hEvent, periods, NULL); - sink->rtBaseTime += periods * sink->rtIntervalTime; + DWORD periods = ((curTime - sink->due_time) / sink->period) + 1; + ReleaseSemaphore(sink->handle, periods, NULL); + sink->due_time += periods * sink->period; } - timeOut = min(timeOut, (sink->rtBaseTime - curTime) / 10000); + timeOut = min(timeOut, (sink->due_time - curTime) / 10000); }
- LeaveCriticalSection(&This->safe); + LeaveCriticalSection(&This->cs);
if (WaitForMultipleObjects(2, handles, FALSE, timeOut) == 0) return 0; @@ -173,8 +173,8 @@ static ULONG WINAPI SystemClockImpl_Release(IReferenceClock *iface) CloseHandle(clock->notify_event); CloseHandle(clock->stop_event); } - clock->safe.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&clock->safe); + clock->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&clock->cs); heap_free(clock); } return refcount; @@ -194,12 +194,12 @@ static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock *iface, REFERENCE_
ret = GetTickCount64() * 10000;
- EnterCriticalSection(&clock->safe); + EnterCriticalSection(&clock->cs);
hr = (ret == clock->last_time) ? S_FALSE : S_OK; *time = clock->last_time = ret;
- LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs);
return hr; } @@ -225,13 +225,13 @@ static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock *iface, if (!(sink = heap_alloc_zero(sizeof(*sink)))) return E_OUTOFMEMORY;
- sink->hEvent = (HANDLE)event; - sink->rtBaseTime = base + offset; - sink->rtIntervalTime = 0; + sink->handle = (HANDLE)event; + sink->due_time = base + offset; + sink->period = 0;
- EnterCriticalSection(&clock->safe); + EnterCriticalSection(&clock->cs); insert_advise_sink(sink, &clock->single_sinks); - LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs);
notify_thread(clock);
@@ -260,13 +260,13 @@ static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, if (!(sink = heap_alloc_zero(sizeof(*sink)))) return E_OUTOFMEMORY;
- sink->hEvent = (HANDLE)semaphore; - sink->rtBaseTime = start; - sink->rtIntervalTime = period; + sink->handle = (HANDLE)semaphore; + sink->due_time = start; + sink->period = period;
- EnterCriticalSection(&clock->safe); + EnterCriticalSection(&clock->cs); insert_advise_sink(sink, &clock->periodic_sinks); - LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs);
notify_thread(clock);
@@ -281,7 +281,7 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR
TRACE("clock %p, cookie %#lx.\n", clock, cookie);
- EnterCriticalSection(&clock->safe); + EnterCriticalSection(&clock->cs);
LIST_FOR_EACH_ENTRY(sink, &clock->single_sinks, struct advise_sink, entry) { @@ -289,7 +289,7 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR { list_remove(&sink->entry); heap_free(sink); - LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs); return S_OK; } } @@ -300,12 +300,12 @@ static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR { list_remove(&sink->entry); heap_free(sink); - LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs); return S_OK; } }
- LeaveCriticalSection(&clock->safe); + LeaveCriticalSection(&clock->cs);
return S_FALSE; } @@ -336,8 +336,8 @@ HRESULT QUARTZ_CreateSystemClock(IUnknown *outer, void **out) object->IReferenceClock_iface.lpVtbl = &SystemClock_Vtbl; list_init(&object->single_sinks); list_init(&object->periodic_sinks); - InitializeCriticalSection(&object->safe); - object->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.safe"); + InitializeCriticalSection(&object->cs); + object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.cs");
return SystemClockImpl_QueryInterface(&object->IReferenceClock_iface, &IID_IReferenceClock, out); }