ReactOS 0.4.17-dev-934-g091855f
systemclock.c
Go to the documentation of this file.
1/*
2 * Implementation of IReferenceClock
3 *
4 * Copyright 2004 Raphael Junqueira
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "quartz_private.h"
22
23#include "wine/debug.h"
24#include <assert.h>
25
27
29
31{
32 struct list entry;
35 int cookie;
36};
37
39{
44
50 CONDITION_VARIABLE cv;
51
52 struct list sinks;
53};
54
56{
57 return (REFERENCE_TIME)timeGetTime() * 10000;
58}
59
60static inline struct system_clock *impl_from_IUnknown(IUnknown *iface)
61{
62 return CONTAINING_RECORD(iface, struct system_clock, IUnknown_inner);
63}
64
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}
84
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}
94
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}
127
128static const IUnknownVtbl system_clock_inner_vtbl =
129{
133};
134
136{
138}
139
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}
188
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}
221
223{
225 return IUnknown_QueryInterface(clock->outer_unk, iid, out);
226}
227
229{
231 return IUnknown_AddRef(clock->outer_unk);
232}
233
235{
237 return IUnknown_Release(clock->outer_unk);
238}
239
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}
262
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}
276
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}
290
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}
315
316static const IReferenceClockVtbl SystemClock_vtbl =
317{
325};
326
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}
HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription)
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
DWORD_PTR HSEMAPHORE
Definition: axcore.idl:60
DWORD_PTR HEVENT
Definition: axcore.idl:61
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static ULONG WINAPI system_clock_inner_AddRef(IUnknown *iface)
Definition: systemclock.c:85
static struct system_clock * impl_from_IReferenceClock(IReferenceClock *iface)
Definition: systemclock.c:135
static const IUnknownVtbl system_clock_inner_vtbl
Definition: systemclock.c:128
static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
Definition: systemclock.c:277
static DWORD WINAPI SystemClockAdviseThread(void *param)
Definition: systemclock.c:140
static LONG cookie_counter
Definition: systemclock.c:28
static struct system_clock * impl_from_IUnknown(IUnknown *iface)
Definition: systemclock.c:60
static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock *iface)
Definition: systemclock.c:228
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
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 system_clock_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: systemclock.c:65
static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
Definition: systemclock.c:291
static ULONG WINAPI system_clock_inner_Release(IUnknown *iface)
Definition: systemclock.c:95
static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
Definition: systemclock.c:240
static REFERENCE_TIME get_current_time(void)
Definition: systemclock.c:55
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
HRESULT system_clock_create(IUnknown *outer, IUnknown **out)
Definition: systemclock.c:327
static const IReferenceClockVtbl SystemClock_vtbl
Definition: systemclock.c:316
#define CloseHandle
Definition: compat.h:739
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
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:59
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:98
_ACRTIMP clock_t __cdecl clock(void)
Definition: time.c:698
DWORD WINAPI timeGetTime(void)
Definition: time.c:466
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
GLfloat param
Definition: glext.h:5796
const char cursor[]
Definition: icontest.c:13
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define S_OK
Definition: intsafe.h:52
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
__u16 time
Definition: mkdosfs.c:8
static HANDLE semaphore
Definition: loader.c:2947
static IUnknown * outer
Definition: compobj.c:82
#define min(a, b)
Definition: monoChain.cc:55
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define TRACE(s)
Definition: solgame.cpp:4
static const char * debugstr_time(REFERENCE_TIME time)
Definition: strmbase.h:32
REFERENCE_TIME period
Definition: systemclock.c:34
struct list entry
Definition: systemclock.c:32
REFERENCE_TIME due_time
Definition: systemclock.c:34
HANDLE handle
Definition: systemclock.c:33
Definition: cookie.c:34
Definition: filter.c:185
struct list sinks
Definition: systemclock.c:52
CONDITION_VARIABLE cv
Definition: systemclock.c:50
IUnknown IUnknown_inner
Definition: systemclock.c:41
LONG thread_created
Definition: systemclock.c:45
IReferenceClock IReferenceClock_iface
Definition: systemclock.c:40
HANDLE thread
Definition: systemclock.c:47
IUnknown * outer_unk
Definition: systemclock.c:42
REFERENCE_TIME last_time
Definition: systemclock.c:48
CRITICAL_SECTION cs
Definition: systemclock.c:49
BOOL thread_stopped
Definition: systemclock.c:46
Definition: dhcpd.h:248
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
PVOID HANDLE
Definition: typedefs.h:73
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1195
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156