📄 time.c
字号:
while (! TIME_TimeToDie)
{
sleep_time = TIME_MMSysTimeCallback(iData);
if (sleep_time == 0)
continue;
rc = WaitForSingleObject(TIME_hWakeEvent, sleep_time);
if (rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0)
{
FIXME("Unexpected error %ld(%ld) in timer thread\n", rc, GetLastError());
break;
}
}
TRACE("Exiting main winmm thread\n");
return 0;
}
/**************************************************************************
* TIME_MMTimeStart
*/
void TIME_MMTimeStart(void)
{
if (!TIME_hMMTimer) {
TIME_TimersList = NULL;
TIME_hWakeEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
TIME_TimeToDie = FALSE;
TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, &WINMM_IData, 0, NULL);
SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL);
}
}
/**************************************************************************
* TIME_MMTimeStop
*/
void TIME_MMTimeStop(void)
{
if (TIME_hMMTimer) {
TIME_TimeToDie = TRUE;
SetEvent(TIME_hWakeEvent);
/* FIXME: in the worst case, we're going to wait 65 seconds here :-( */
WaitForSingleObject(TIME_hMMTimer, INFINITE);
CloseHandle(TIME_hMMTimer);
CloseHandle(TIME_hWakeEvent);
TIME_hMMTimer = 0;
TIME_TimersList = NULL;
}
}
/**************************************************************************
* timeGetSystemTime [WINMM.@]
*/
MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize)
{
if (wSize >= sizeof(*lpTime)) {
lpTime->wType = TIME_MS;
lpTime->u.ms = GetTickCount();
}
return 0;
}
/**************************************************************************
* TIME_SetEventInternal [internal]
*/
WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
LPTIMECALLBACK lpFunc, DWORD dwUser, UINT wFlags)
{
WORD wNewID = 0;
LPWINE_TIMERENTRY lpNewTimer;
LPWINE_TIMERENTRY lpTimer;
TRACE("(%u, %u, %p, %08lX, %04X);\n", wDelay, wResol, lpFunc, dwUser, wFlags);
if (wDelay < MMSYSTIME_MININTERVAL || wDelay > MMSYSTIME_MAXINTERVAL)
return 0;
lpNewTimer = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_TIMERENTRY));
if (lpNewTimer == NULL)
return 0;
TIME_MMTimeStart();
lpNewTimer->wDelay = wDelay;
lpNewTimer->dwTriggerTime = GetTickCount() + wDelay;
/* FIXME - wResol is not respected, although it is not clear
that we could change our precision meaningfully */
lpNewTimer->wResol = wResol;
lpNewTimer->lpFunc = lpFunc;
lpNewTimer->dwUser = dwUser;
lpNewTimer->wFlags = wFlags;
EnterCriticalSection(&WINMM_IData.cs);
if ((wFlags & TIME_KILL_SYNCHRONOUS) && !TIME_hKillEvent)
TIME_hKillEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
for (lpTimer = TIME_TimersList; lpTimer != NULL; lpTimer = lpTimer->lpNext) {
wNewID = max(wNewID, lpTimer->wTimerID);
}
lpNewTimer->lpNext = TIME_TimersList;
TIME_TimersList = lpNewTimer;
lpNewTimer->wTimerID = wNewID + 1;
LeaveCriticalSection(&WINMM_IData.cs);
/* Wake the service thread in case there is work to be done */
SetEvent(TIME_hWakeEvent);
TRACE("=> %u\n", wNewID + 1);
return wNewID + 1;
}
/**************************************************************************
* timeSetEvent [WINMM.@]
*/
MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
DWORD_PTR dwUser, UINT wFlags)
{
if (wFlags & WINE_TIMER_IS32)
WARN("Unknown windows flag... wine internally used.. ooch\n");
return TIME_SetEventInternal(wDelay, wResol, lpFunc,
dwUser, wFlags|WINE_TIMER_IS32);
}
/**************************************************************************
* timeKillEvent [WINMM.@]
*/
MMRESULT WINAPI timeKillEvent(UINT wID)
{
LPWINE_TIMERENTRY lpSelf = NULL, *lpTimer;
TRACE("(%u)\n", wID);
EnterCriticalSection(&WINMM_IData.cs);
/* remove WINE_TIMERENTRY from list */
for (lpTimer = &TIME_TimersList; *lpTimer; lpTimer = &(*lpTimer)->lpNext) {
if (wID == (*lpTimer)->wTimerID) {
lpSelf = *lpTimer;
/* unlink timer of id 'wID' */
*lpTimer = (*lpTimer)->lpNext;
break;
}
}
LeaveCriticalSection(&WINMM_IData.cs);
if (!lpSelf)
{
WARN("wID=%u is not a valid timer ID\n", wID);
return MMSYSERR_INVALPARAM;
}
if (lpSelf->wFlags & TIME_KILL_SYNCHRONOUS)
WaitForSingleObject(TIME_hKillEvent, INFINITE);
HeapFree(GetProcessHeap(), 0, lpSelf);
return TIMERR_NOERROR;
}
/**************************************************************************
* timeGetDevCaps [WINMM.@]
*/
MMRESULT WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
{
TRACE("(%p, %u)\n", lpCaps, wSize);
if (lpCaps == 0) {
WARN("invalid lpCaps\n");
return TIMERR_NOCANDO;
}
if (wSize < sizeof(TIMECAPS)) {
WARN("invalid wSize\n");
return TIMERR_NOCANDO;
}
lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
return TIMERR_NOERROR;
}
/**************************************************************************
* timeBeginPeriod [WINMM.@]
*/
MMRESULT WINAPI timeBeginPeriod(UINT wPeriod)
{
if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
return TIMERR_NOCANDO;
if (wPeriod > MMSYSTIME_MININTERVAL)
{
WARN("Stub; we set our timer resolution at minimum\n");
}
return 0;
}
/**************************************************************************
* timeEndPeriod [WINMM.@]
*/
MMRESULT WINAPI timeEndPeriod(UINT wPeriod)
{
if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
return TIMERR_NOCANDO;
if (wPeriod > MMSYSTIME_MININTERVAL)
{
WARN("Stub; we set our timer resolution at minimum\n");
}
return 0;
}
/**************************************************************************
* timeGetTime [MMSYSTEM.607]
* timeGetTime [WINMM.@]
*/
DWORD WINAPI timeGetTime(void)
{
#if defined(COMMENTOUTPRIORTODELETING)
DWORD count;
/* FIXME: releasing the win16 lock here is a temporary hack (I hope)
* that lets mciavi.drv run correctly
*/
if (pFnReleaseThunkLock) pFnReleaseThunkLock(&count);
if (pFnRestoreThunkLock) pFnRestoreThunkLock(count);
#endif
return GetTickCount();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -