ReactOS 0.4.17-dev-934-g091855f
systemclock.c File Reference
#include "quartz_private.h"
#include "wine/debug.h"
#include <assert.h>
Include dependency graph for systemclock.c:

Go to the source code of this file.

Classes

struct  advise_sink
 
struct  system_clock
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (quartz)
 
static REFERENCE_TIME get_current_time (void)
 
static struct system_clock * impl_from_IUnknown (IUnknown *iface)
 
static HRESULT WINAPI system_clock_inner_QueryInterface (IUnknown *iface, REFIID iid, void **out)
 
static ULONG WINAPI system_clock_inner_AddRef (IUnknown *iface)
 
static ULONG WINAPI system_clock_inner_Release (IUnknown *iface)
 
static struct system_clock * impl_from_IReferenceClock (IReferenceClock *iface)
 
static DWORD WINAPI SystemClockAdviseThread (void *param)
 
static HRESULT add_sink (struct system_clock *clock, DWORD_PTR handle, REFERENCE_TIME due_time, REFERENCE_TIME period, DWORD_PTR *cookie)
 
static HRESULT WINAPI SystemClockImpl_QueryInterface (IReferenceClock *iface, REFIID iid, void **out)
 
static ULONG WINAPI SystemClockImpl_AddRef (IReferenceClock *iface)
 
static ULONG WINAPI SystemClockImpl_Release (IReferenceClock *iface)
 
static HRESULT WINAPI SystemClockImpl_GetTime (IReferenceClock *iface, REFERENCE_TIME *time)
 
static HRESULT WINAPI SystemClockImpl_AdviseTime (IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
 
static HRESULT WINAPI SystemClockImpl_AdvisePeriodic (IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
 
static HRESULT WINAPI SystemClockImpl_Unadvise (IReferenceClock *iface, DWORD_PTR cookie)
 
HRESULT system_clock_create (IUnknown *outer, IUnknown **out)
 

Variables

static LONG cookie_counter
 
static const IUnknownVtbl system_clock_inner_vtbl
 
static const IReferenceClockVtbl SystemClock_vtbl
 

Function Documentation

◆ add_sink()

static HRESULT add_sink ( struct system_clock *  clock,
DWORD_PTR  handle,
REFERENCE_TIME  due_time,
REFERENCE_TIME  period,
DWORD_PTR *  cookie 
)
static

Definition at line 189 of file systemclock.c.

191{
192 struct advise_sink *sink;
193
194 if (!handle)
195 return E_INVALIDARG;
196
197 if (!cookie)
198 return E_POINTER;
199
200 if (!(sink = heap_alloc_zero(sizeof(*sink))))
201 return E_OUTOFMEMORY;
202
203 sink->handle = (HANDLE)handle;
204 sink->due_time = due_time;
205 sink->period = period;
207 *cookie = sink->cookie;
208
210 list_add_tail(&clock->sinks, &sink->entry);
212
213 if (!InterlockedCompareExchange(&clock->thread_created, TRUE, FALSE))
214 {
216 }
218
219 return S_OK;
220}
#define InterlockedIncrement
Definition: armddk.h:53
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static DWORD WINAPI SystemClockAdviseThread(void *param)
Definition: systemclock.c:140
static LONG cookie_counter
Definition: systemclock.c:28
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:98
_ACRTIMP clock_t __cdecl clock(void)
Definition: time.c:698
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define S_OK
Definition: intsafe.h:52
REFERENCE_TIME period
Definition: systemclock.c:34
REFERENCE_TIME due_time
Definition: systemclock.c:34
Definition: cookie.c:34
PVOID HANDLE
Definition: typedefs.h:73
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define E_POINTER
Definition: winerror.h:3480

Referenced by SystemClockImpl_AdvisePeriodic(), and SystemClockImpl_AdviseTime().

◆ get_current_time()

static REFERENCE_TIME get_current_time ( void  )
static

Definition at line 55 of file systemclock.c.

56{
57 return (REFERENCE_TIME)timeGetTime() * 10000;
58}
DWORD WINAPI timeGetTime(void)
Definition: time.c:466
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9

Referenced by SystemClockAdviseThread(), and SystemClockImpl_GetTime().

◆ impl_from_IReferenceClock()

static struct system_clock * impl_from_IReferenceClock ( IReferenceClock *  iface)
inlinestatic

Definition at line 135 of file systemclock.c.

136{
137 return CONTAINING_RECORD(iface, struct system_clock, IReferenceClock_iface);
138}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by SystemClockImpl_AddRef(), SystemClockImpl_AdvisePeriodic(), SystemClockImpl_AdviseTime(), SystemClockImpl_GetTime(), SystemClockImpl_QueryInterface(), SystemClockImpl_Release(), and SystemClockImpl_Unadvise().

◆ impl_from_IUnknown()

static struct system_clock * impl_from_IUnknown ( IUnknown *  iface)
inlinestatic

Definition at line 60 of file systemclock.c.

61{
62 return CONTAINING_RECORD(iface, struct system_clock, IUnknown_inner);
63}

Referenced by system_clock_inner_AddRef(), system_clock_inner_QueryInterface(), and system_clock_inner_Release().

◆ system_clock_create()

HRESULT system_clock_create ( IUnknown *  outer,
IUnknown **  out 
)

Definition at line 327 of file systemclock.c.

328{
329 struct system_clock *object;
330
331 TRACE("outer %p, out %p.\n", outer, out);
332
333 if (!(object = heap_alloc_zero(sizeof(*object))))
334 {
335 *out = NULL;
336 return E_OUTOFMEMORY;
337 }
338
339 object->IReferenceClock_iface.lpVtbl = &SystemClock_vtbl;
340 object->IUnknown_inner.lpVtbl = &system_clock_inner_vtbl;
341 object->outer_unk = outer ? outer : &object->IUnknown_inner;
342 object->refcount = 1;
343 list_init(&object->sinks);
345 object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.cs");
346
347 TRACE("Created system clock %p.\n", object);
348 *out = &object->IUnknown_inner;
349
350 return S_OK;
351}
static void list_init(struct list_entry *head)
Definition: list.h:51
static const IUnknownVtbl system_clock_inner_vtbl
Definition: systemclock.c:128
static const IReferenceClockVtbl SystemClock_vtbl
Definition: systemclock.c:316
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
static IUnknown * outer
Definition: compobj.c:82
#define TRACE(s)
Definition: solgame.cpp:4
#define DWORD_PTR
Definition: treelist.c:76
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156

Referenced by dsound_render_create().

◆ system_clock_inner_AddRef()

static ULONG WINAPI system_clock_inner_AddRef ( IUnknown *  iface)
static

Definition at line 85 of file systemclock.c.

86{
87 struct system_clock *clock = impl_from_IUnknown(iface);
89
90 TRACE("%p increasing refcount to %lu.\n", clock, refcount);
91
92 return refcount;
93}
static struct system_clock * impl_from_IUnknown(IUnknown *iface)
Definition: systemclock.c:60
uint32_t ULONG
Definition: typedefs.h:59

◆ system_clock_inner_QueryInterface()

static HRESULT WINAPI system_clock_inner_QueryInterface ( IUnknown *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 65 of file systemclock.c.

66{
67 struct system_clock *clock = impl_from_IUnknown(iface);
68 TRACE("clock %p, iid %s, out %p.\n", clock, debugstr_guid(iid), out);
69
70 if (IsEqualGUID(iid, &IID_IUnknown))
71 *out = iface;
72 else if (IsEqualGUID(iid, &IID_IReferenceClock))
73 *out = &clock->IReferenceClock_iface;
74 else
75 {
76 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
77 *out = NULL;
78 return E_NOINTERFACE;
79 }
80
81 IUnknown_AddRef((IUnknown *)*out);
82 return S_OK;
83}
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ system_clock_inner_Release()

static ULONG WINAPI system_clock_inner_Release ( IUnknown *  iface)
static

Definition at line 95 of file systemclock.c.

96{
97 struct system_clock *clock = impl_from_IUnknown(iface);
99 struct advise_sink *sink, *cursor;
100
101 TRACE("%p decreasing refcount to %lu.\n", clock, refcount);
102
103 if (!refcount)
104 {
105 if (clock->thread)
106 {
108 clock->thread_stopped = TRUE;
112 CloseHandle(clock->thread);
113 }
114
116 {
117 list_remove(&sink->entry);
119 }
120
121 clock->cs.DebugInfo->Spare[0] = 0;
124 }
125 return refcount;
126}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedDecrement
Definition: armddk.h:52
static void list_remove(struct list_entry *entry)
Definition: list.h:90
#define CloseHandle
Definition: compat.h:739
#define INFINITE
Definition: serial.h:102
const char cursor[]
Definition: icontest.c:13
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ SystemClockAdviseThread()

static DWORD WINAPI SystemClockAdviseThread ( void *  param)
static

Definition at line 140 of file systemclock.c.

141{
142 struct system_clock *clock = param;
143 struct advise_sink *sink, *cursor;
144 REFERENCE_TIME current_time;
145
146 TRACE("Starting advise thread for clock %p.\n", clock);
147 SetThreadDescription(GetCurrentThread(), L"wine_qz_clock_advise");
148
149 for (;;)
150 {
152
154
155 current_time = get_current_time();
156
158 {
159 if (sink->due_time <= current_time)
160 {
161 if (sink->period)
162 {
163 DWORD periods = ((current_time - sink->due_time) / sink->period) + 1;
164 ReleaseSemaphore(sink->handle, periods, NULL);
165 sink->due_time += periods * sink->period;
166 }
167 else
168 {
169 SetEvent(sink->handle);
170 list_remove(&sink->entry);
172 continue;
173 }
174 }
175
176 timeout = min(timeout, (sink->due_time - current_time) / 10000);
177 }
178
180 if (clock->thread_stopped)
181 {
183 return 0;
184 }
186 }
187}
HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription)
static REFERENCE_TIME get_current_time(void)
Definition: systemclock.c:55
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:59
#define L(x)
Definition: resources.c:13
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat param
Definition: glext.h:5796
#define min(a, b)
Definition: monoChain.cc:55
Definition: dhcpd.h:248
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore(IN HANDLE hSemaphore, IN LONG lReleaseCount, IN LPLONG lpPreviousCount)
Definition: synch.c:491
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1195

Referenced by add_sink().

◆ SystemClockImpl_AddRef()

static ULONG WINAPI SystemClockImpl_AddRef ( IReferenceClock *  iface)
static

Definition at line 228 of file systemclock.c.

229{
231 return IUnknown_AddRef(clock->outer_unk);
232}
static struct system_clock * impl_from_IReferenceClock(IReferenceClock *iface)
Definition: systemclock.c:135

◆ SystemClockImpl_AdvisePeriodic()

static HRESULT WINAPI SystemClockImpl_AdvisePeriodic ( IReferenceClock *  iface,
REFERENCE_TIME  start,
REFERENCE_TIME  period,
HSEMAPHORE  semaphore,
DWORD_PTR *  cookie 
)
static

Definition at line 277 of file systemclock.c.

279{
281
282 TRACE("clock %p, start %s, period %s, semaphore %#Ix, cookie %p.\n",
284
285 if (start <= 0 || period <= 0)
286 return E_INVALIDARG;
287
288 return add_sink(clock, semaphore, start, period, cookie);
289}
static HRESULT add_sink(struct system_clock *clock, DWORD_PTR handle, REFERENCE_TIME due_time, REFERENCE_TIME period, DWORD_PTR *cookie)
Definition: systemclock.c:189
GLuint start
Definition: gl.h:1545
static HANDLE semaphore
Definition: loader.c:2947
static const char * debugstr_time(REFERENCE_TIME time)
Definition: strmbase.h:32

◆ SystemClockImpl_AdviseTime()

static HRESULT WINAPI SystemClockImpl_AdviseTime ( IReferenceClock *  iface,
REFERENCE_TIME  base,
REFERENCE_TIME  offset,
HEVENT  event,
DWORD_PTR *  cookie 
)
static

Definition at line 263 of file systemclock.c.

265{
267
268 TRACE("clock %p, base %s, offset %s, event %#Ix, cookie %p.\n",
270
271 if (base + offset <= 0)
272 return E_INVALIDARG;
273
274 return add_sink(clock, event, base + offset, 0, cookie);
275}
GLintptr offset
Definition: glext.h:5920
Definition: filter.c:185

◆ SystemClockImpl_GetTime()

static HRESULT WINAPI SystemClockImpl_GetTime ( IReferenceClock *  iface,
REFERENCE_TIME *  time 
)
static

Definition at line 240 of file systemclock.c.

241{
244 HRESULT hr;
245
246 if (!time) {
247 return E_POINTER;
248 }
249
251
253
254 hr = (ret == clock->last_time) ? S_FALSE : S_OK;
255 *time = clock->last_time = ret;
256
258
259 TRACE("clock %p, time %p, returning %s.\n", clock, time, debugstr_time(ret));
260 return hr;
261}
HRESULT hr
Definition: delayimp.cpp:582
return ret
Definition: mutex.c:147
__u16 time
Definition: mkdosfs.c:8
#define S_FALSE
Definition: winerror.h:3451

◆ SystemClockImpl_QueryInterface()

static HRESULT WINAPI SystemClockImpl_QueryInterface ( IReferenceClock *  iface,
REFIID  iid,
void **  out 
)
static

Definition at line 222 of file systemclock.c.

223{
225 return IUnknown_QueryInterface(clock->outer_unk, iid, out);
226}

◆ SystemClockImpl_Release()

static ULONG WINAPI SystemClockImpl_Release ( IReferenceClock *  iface)
static

Definition at line 234 of file systemclock.c.

235{
237 return IUnknown_Release(clock->outer_unk);
238}

◆ SystemClockImpl_Unadvise()

static HRESULT WINAPI SystemClockImpl_Unadvise ( IReferenceClock *  iface,
DWORD_PTR  cookie 
)
static

Definition at line 291 of file systemclock.c.

292{
294 struct advise_sink *sink;
295
296 TRACE("clock %p, cookie %#Ix.\n", clock, cookie);
297
299
301 {
302 if (sink->cookie == cookie)
303 {
304 list_remove(&sink->entry);
307 return S_OK;
308 }
309 }
310
312
313 return S_FALSE;
314}
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( quartz  )

Variable Documentation

◆ cookie_counter

LONG cookie_counter
static

Definition at line 28 of file systemclock.c.

Referenced by add_sink(), and wined3d_adapter_register_budget_change_notification().

◆ system_clock_inner_vtbl

const IUnknownVtbl system_clock_inner_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI system_clock_inner_AddRef(IUnknown *iface)
Definition: systemclock.c:85
static HRESULT WINAPI system_clock_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: systemclock.c:65
static ULONG WINAPI system_clock_inner_Release(IUnknown *iface)
Definition: systemclock.c:95

Definition at line 128 of file systemclock.c.

Referenced by system_clock_create().

◆ SystemClock_vtbl

const IReferenceClockVtbl SystemClock_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
Definition: systemclock.c:277
static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock *iface)
Definition: systemclock.c:228
static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
Definition: systemclock.c:263
static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
Definition: systemclock.c:291
static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
Definition: systemclock.c:240
static ULONG WINAPI SystemClockImpl_Release(IReferenceClock *iface)
Definition: systemclock.c:234
static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock *iface, REFIID iid, void **out)
Definition: systemclock.c:222

Definition at line 316 of file systemclock.c.

Referenced by system_clock_create().