Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
9db6037d
Commit
9db6037d
authored
Jan 12, 2004
by
Eric Pouech
Committed by
Alexandre Julliard
Jan 12, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- implemented TIME_KILL_SYCHRONOUS timer flags
- timeKillTimer is now thread safe - replaced some iData attributes by global variables
parent
370a18f7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
63 deletions
+73
-63
mmsystem.c
dlls/winmm/mmsystem.c
+1
-1
time.c
dlls/winmm/time.c
+70
-55
winemm.h
dlls/winmm/winemm.h
+2
-7
No files found.
dlls/winmm/mmsystem.c
View file @
9db6037d
...
...
@@ -2529,7 +2529,7 @@ MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
if
(
wSize
>=
sizeof
(
*
lpTime
))
{
lpTime
->
wType
=
TIME_MS
;
TIME_MMTimeStart
();
lpTime
->
u
.
ms
=
WINMM_
IData
->
mm
SysTimeMS
;
lpTime
->
u
.
ms
=
WINMM_SysTimeMS
;
TRACE
(
"=> %lu
\n
"
,
lpTime
->
u
.
ms
);
}
...
...
dlls/winmm/time.c
View file @
9db6037d
...
...
@@ -42,6 +42,11 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
mmtime
);
static
HANDLE
TIME_hMMTimer
;
static
LPWINE_TIMERENTRY
TIME_TimersList
;
static
HANDLE
TIME_hKillEvent
;
DWORD
WINMM_SysTimeMS
;
/*
* FIXME
* We're using "1" as the mininum resolution to the timer,
...
...
@@ -90,15 +95,18 @@ static void TIME_TriggerCallBack(LPWINE_TIMERENTRY lpTimer)
*/
static
void
CALLBACK
TIME_MMSysTimeCallback
(
LPWINE_MM_IDATA
iData
)
{
LPWINE_TIMERENTRY
lpTimer
,
lpNextTimer
;
DWORD
delta
=
GetTickCount
()
-
iData
->
mmSysTimeMS
;
static
int
nSizeLpTimers
;
static
LPWINE_TIMERENTRY
lpTimers
;
LPWINE_TIMERENTRY
timer
,
*
ptimer
,
*
next_ptimer
;
DWORD
delta
=
GetTickCount
()
-
WINMM_SysTimeMS
;
int
idx
;
TRACE
(
"Time delta: %ld
\n
"
,
delta
);
while
(
delta
>=
MMSYSTIME_MININTERVAL
)
{
delta
-=
MMSYSTIME_MININTERVAL
;
iData
->
mm
SysTimeMS
+=
MMSYSTIME_MININTERVAL
;
WINMM_
SysTimeMS
+=
MMSYSTIME_MININTERVAL
;
/* since timeSetEvent() and timeKillEvent() can be called
* from 16 bit code, there are cases where win16 lock is
...
...
@@ -109,48 +117,52 @@ static void CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData)
* situation).
* To cope with that, we just copy the WINE_TIMERENTRY struct
* that need to trigger the callback, and call it without the
* mm timer crit sect locked.
The bad side of this
* implementation is that, in some cases, the callback may be
* invoked *after* a timer has been destroyed..
.
* EPP 99/07/13
* mm timer crit sect locked.
* the hKillTimeEvent is used to mark the section where we
* handle the callbacks so we can do synchronous kills
.
* EPP 99/07/13
, updated 04/01/10
*/
idx
=
0
;
EnterCriticalSection
(
&
iData
->
cs
);
for
(
lpTimer
=
iData
->
lpTimerList
;
lpTimer
!=
NULL
;
)
{
lpNextTimer
=
lpTimer
->
lpNext
;
if
(
lpTimer
->
uCurTime
<
MMSYSTIME_MININTERVAL
)
{
for
(
ptimer
=
&
TIME_TimersList
;
*
ptimer
!=
NULL
;
)
{
timer
=
*
ptimer
;
next_ptimer
=
&
timer
->
lpNext
;
if
(
timer
->
uCurTime
<
MMSYSTIME_MININTERVAL
)
{
/* since lpTimer->wDelay is >= MININTERVAL, wCurTime value
* shall be correct (>= 0)
*/
lpTimer
->
uCurTime
+=
lpTimer
->
wDelay
-
MMSYSTIME_MININTERVAL
;
if
(
lpTimer
->
lpFunc
)
{
if
(
idx
==
iData
->
nSizeLpTimers
)
{
if
(
iData
->
lpTimers
)
iData
->
lpTimers
=
(
LPWINE_TIMERENTRY
)
HeapReAlloc
(
GetProcessHeap
(),
0
,
iData
->
lpTimers
,
++
iData
->
nSizeLpTimers
*
sizeof
(
WINE_TIMERENTRY
));
timer
->
uCurTime
+=
timer
->
wDelay
-
MMSYSTIME_MININTERVAL
;
if
(
timer
->
lpFunc
)
{
if
(
idx
==
nSizeLpTimers
)
{
if
(
lpTimers
)
lpTimers
=
(
LPWINE_TIMERENTRY
)
HeapReAlloc
(
GetProcessHeap
(),
0
,
lpTimers
,
++
nSizeLpTimers
*
sizeof
(
WINE_TIMERENTRY
));
else
iData
->
lpTimers
=
(
LPWINE_TIMERENTRY
)
lpTimers
=
(
LPWINE_TIMERENTRY
)
HeapAlloc
(
GetProcessHeap
(),
0
,
++
iData
->
nSizeLpTimers
*
sizeof
(
WINE_TIMERENTRY
));
++
nSizeLpTimers
*
sizeof
(
WINE_TIMERENTRY
));
}
iData
->
lpTimers
[
idx
++
]
=
*
lpT
imer
;
lpTimers
[
idx
++
]
=
*
t
imer
;
}
/* TIME_ONESHOT is defined as 0 */
if
(
!
(
lpTimer
->
wFlags
&
TIME_PERIODIC
))
timeKillEvent
(
lpTimer
->
wTimerID
);
if
(
!
(
timer
->
wFlags
&
TIME_PERIODIC
))
{
/* unlink timer from timers list */
*
ptimer
=
*
next_ptimer
;
HeapFree
(
GetProcessHeap
(),
0
,
timer
);
}
}
else
{
lpT
imer
->
uCurTime
-=
MMSYSTIME_MININTERVAL
;
t
imer
->
uCurTime
-=
MMSYSTIME_MININTERVAL
;
}
lpTimer
=
lpNextT
imer
;
ptimer
=
next_pt
imer
;
}
if
(
TIME_hKillEvent
)
ResetEvent
(
TIME_hKillEvent
);
LeaveCriticalSection
(
&
iData
->
cs
);
while
(
idx
>
0
)
{
TIME_TriggerCallBack
(
&
iData
->
lpTimers
[
--
idx
]);
}
while
(
idx
>
0
)
TIME_TriggerCallBack
(
&
lpTimers
[
--
idx
]);
if
(
TIME_hKillEvent
)
SetEvent
(
TIME_hKillEvent
);
}
}
...
...
@@ -160,7 +172,7 @@ static void CALLBACK TIME_MMSysTimeCallback(LPWINE_MM_IDATA iData)
static
DWORD
CALLBACK
TIME_MMSysTimeThread
(
LPVOID
arg
)
{
LPWINE_MM_IDATA
iData
=
(
LPWINE_MM_IDATA
)
arg
;
volatile
HANDLE
*
pActive
=
(
volatile
HANDLE
*
)
&
iData
->
hMMTimer
;
volatile
HANDLE
*
pActive
=
(
volatile
HANDLE
*
)
&
TIME_
hMMTimer
;
DWORD
last_time
,
cur_time
;
usleep
(
MMSYSTIME_STDINTERVAL
*
1000
);
...
...
@@ -184,10 +196,10 @@ void TIME_MMTimeStart(void)
* mm timers are active, but this would require to keep mmSysTimeMS up-to-date
* without being incremented within the service thread callback.
*/
if
(
!
WINMM_IData
->
hMMTimer
)
{
WINMM_
IData
->
mm
SysTimeMS
=
GetTickCount
();
WINMM_IData
->
lpTimer
List
=
NULL
;
WINMM_IData
->
hMMTimer
=
CreateThread
(
NULL
,
0
,
TIME_MMSysTimeThread
,
WINMM_IData
,
0
,
NULL
);
if
(
!
TIME_
hMMTimer
)
{
WINMM_SysTimeMS
=
GetTickCount
();
TIME_Timers
List
=
NULL
;
TIME_
hMMTimer
=
CreateThread
(
NULL
,
0
,
TIME_MMSysTimeThread
,
WINMM_IData
,
0
,
NULL
);
}
}
...
...
@@ -196,9 +208,10 @@ void TIME_MMTimeStart(void)
*/
void
TIME_MMTimeStop
(
void
)
{
if
(
WINMM_IData
->
hMMTimer
)
{
HANDLE
hMMTimer
=
WINMM_IData
->
hMMTimer
;
WINMM_IData
->
hMMTimer
=
0
;
/* FIXME: in the worst case, we're going to wait 65 seconds here :-( */
if
(
TIME_hMMTimer
)
{
HANDLE
hMMTimer
=
TIME_hMMTimer
;
TIME_hMMTimer
=
0
;
WaitForSingleObject
(
hMMTimer
,
INFINITE
);
CloseHandle
(
hMMTimer
);
}
...
...
@@ -214,7 +227,7 @@ MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize)
if
(
wSize
>=
sizeof
(
*
lpTime
))
{
TIME_MMTimeStart
();
lpTime
->
wType
=
TIME_MS
;
lpTime
->
u
.
ms
=
WINMM_
IData
->
mm
SysTimeMS
;
lpTime
->
u
.
ms
=
WINMM_SysTimeMS
;
TRACE
(
"=> %lu
\n
"
,
lpTime
->
u
.
ms
);
}
...
...
@@ -252,12 +265,15 @@ WORD TIME_SetEventInternal(UINT wDelay, UINT wResol,
EnterCriticalSection
(
&
WINMM_IData
->
cs
);
for
(
lpTimer
=
WINMM_IData
->
lpTimerList
;
lpTimer
!=
NULL
;
lpTimer
=
lpTimer
->
lpNext
)
{
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
=
WINMM_IData
->
lpTimer
List
;
WINMM_IData
->
lpTimer
List
=
lpNewTimer
;
lpNewTimer
->
lpNext
=
TIME_Timers
List
;
TIME_Timers
List
=
lpNewTimer
;
lpNewTimer
->
wTimerID
=
wNewID
+
1
;
LeaveCriticalSection
(
&
WINMM_IData
->
cs
);
...
...
@@ -285,31 +301,30 @@ MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
*/
MMRESULT
WINAPI
timeKillEvent
(
UINT
wID
)
{
LPWINE_TIMERENTRY
*
lpTimer
;
MMRESULT
ret
=
MMSYSERR_INVALPARAM
;
LPWINE_TIMERENTRY
lpSelf
=
NULL
,
*
lpTimer
;
TRACE
(
"(%u)
\n
"
,
wID
);
EnterCriticalSection
(
&
WINMM_IData
->
cs
);
/* remove WINE_TIMERENTRY from list */
for
(
lpTimer
=
&
WINMM_IData
->
lpTimer
List
;
*
lpTimer
;
lpTimer
=
&
(
*
lpTimer
)
->
lpNext
)
{
for
(
lpTimer
=
&
TIME_Timers
List
;
*
lpTimer
;
lpTimer
=
&
(
*
lpTimer
)
->
lpNext
)
{
if
(
wID
==
(
*
lpTimer
)
->
wTimerID
)
{
lpSelf
=
*
lpTimer
;
/* unlink timer of id 'wID' */
*
lpTimer
=
(
*
lpTimer
)
->
lpNext
;
break
;
}
}
LeaveCriticalSection
(
&
WINMM_IData
->
cs
);
if
(
*
lpTimer
)
{
LPWINE_TIMERENTRY
lpTemp
=
*
lpTimer
;
/* unlink timer of id 'wID' */
*
lpTimer
=
(
*
lpTimer
)
->
lpNext
;
HeapFree
(
GetProcessHeap
(),
0
,
lpTemp
);
ret
=
TIMERR_NOERROR
;
}
else
{
WARN
(
"wID=%u is not a valid timer ID
\n
"
,
wID
);
if
(
!
lpSelf
)
{
WARN
(
"wID=%u is not a valid timer ID
\n
"
,
wID
);
return
MMSYSERR_INVALPARAM
;
}
return
ret
;
if
(
lpSelf
->
wFlags
&
TIME_KILL_SYNCHRONOUS
)
WaitForSingleObject
(
TIME_hKillEvent
,
INFINITE
);
HeapFree
(
GetProcessHeap
(),
0
,
lpSelf
);
return
TIMERR_NOERROR
;
}
/**************************************************************************
...
...
@@ -361,5 +376,5 @@ DWORD WINAPI timeGetTime(void)
if
(
pFnReleaseThunkLock
)
pFnReleaseThunkLock
(
&
count
);
TIME_MMTimeStart
();
if
(
pFnRestoreThunkLock
)
pFnRestoreThunkLock
(
count
);
return
WINMM_
IData
->
mm
SysTimeMS
;
return
WINMM_SysTimeMS
;
}
dlls/winmm/winemm.h
View file @
9db6037d
...
...
@@ -201,12 +201,6 @@ typedef struct tagWINE_MM_IDATA {
HANDLE
hWinMM32Instance
;
HANDLE
hWinMM16Instance
;
CRITICAL_SECTION
cs
;
/* mm timer part */
HANDLE
hMMTimer
;
DWORD
mmSysTimeMS
;
LPWINE_TIMERENTRY
lpTimerList
;
int
nSizeLpTimers
;
LPWINE_TIMERENTRY
lpTimers
;
/* mci part */
LPWINE_MCIDRIVER
lpMciDrvs
;
/* low level drivers (unused yet) */
...
...
@@ -242,7 +236,7 @@ DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwParam2);
DWORD
MMDRV_Close
(
LPWINE_MLD
mld
,
UINT
wMsg
);
LPWINE_MLD
MMDRV_Get
(
HANDLE
hndl
,
UINT
type
,
BOOL
bCanBeID
);
LPWINE_MLD
MMDRV_GetRelated
(
HANDLE
hndl
,
UINT
srcType
,
BOOL
bSrcCanBeID
,
UINT
dstTyped
);
DWORD
MMDRV_Message
(
LPWINE_MLD
mld
,
UINT
wMsg
,
DWORD_PTR
dwParam1
,
DWORD_PTR
dwParam2
,
BOOL
bFrom32
);
DWORD
MMDRV_Message
(
LPWINE_MLD
mld
,
UINT
wMsg
,
DWORD_PTR
dwParam1
,
DWORD_PTR
dwParam2
,
BOOL
bFrom32
);
UINT
MMDRV_PhysicalFeatures
(
LPWINE_MLD
mld
,
UINT
uMsg
,
DWORD
dwParam1
,
DWORD
dwParam2
);
BOOL
MMDRV_Is32
(
unsigned
int
);
void
MMDRV_InstallMap
(
unsigned
int
,
MMDRV_MAPFUNC
,
MMDRV_UNMAPFUNC
,
...
...
@@ -290,6 +284,7 @@ void TIME_MMTimeStop(void);
/* Global variables */
extern
LPWINE_MM_IDATA
WINMM_IData
;
extern
DWORD
WINMM_SysTimeMS
;
/* pointers to 16 bit functions (if sibling MMSYSTEM.DLL is loaded
* NULL otherwise
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment