Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Yoann Laissus
wine
Commits
bba54db0
Commit
bba54db0
authored
25 years ago
by
Eric Pouech
Committed by
Alexandre Julliard
25 years ago
Browse files
Options
Downloads
Patches
Plain Diff
No longer using global vars (shared data) for mm timers, but a
specific structure for each attached process.
parent
2858ac99
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/multimedia.h
+30
-1
30 additions, 1 deletion
include/multimedia.h
multimedia/time.c
+75
-71
75 additions, 71 deletions
multimedia/time.c
with
105 additions
and
72 deletions
include/multimedia.h
+
30
−
1
View file @
bba54db0
...
...
@@ -13,6 +13,7 @@
#define __WINE_MULTIMEDIA_H
#include
"mmsystem.h"
#include
"winbase.h"
#define MAX_MIDIINDRV (16)
/* For now I'm making 16 the maximum number of midi devices one can
...
...
@@ -84,6 +85,33 @@ typedef enum {
MCI_MAP_PASS
/* ok, no memory allocated. to be sent to 32 bit proc */
}
MCI_MapType
;
typedef
struct
tagTIMERENTRY
{
UINT
wDelay
;
UINT
wResol
;
FARPROC16
lpFunc
;
DWORD
dwUser
;
UINT
wFlags
;
UINT
wTimerID
;
UINT
wCurTime
;
UINT
isWin32
;
struct
tagTIMERENTRY
*
lpNext
;
}
TIMERENTRY
,
*
LPTIMERENTRY
;
typedef
struct
tagWINE_MM_IDATA
{
/* iData reference */
DWORD
dwThisProcess
;
struct
tagWINE_MM_IDATA
*
lpNextIData
;
/* winmm part */
HANDLE
hWinMM32Instance
;
HANDLE
hWinMM16Instance
;
HANDLE
h16Module32
;
/* mm timer part */
HANDLE
hMMTimer
;
DWORD
mmSysTimeMS
;
LPTIMERENTRY
lpTimerList
;
CRITICAL_SECTION
cs
;
}
WINE_MM_IDATA
,
*
LPWINE_MM_IDATA
;
/* function prototypes */
#define MCI_GetDrv(wDevID) (&mciDrv[MCI_DevIDToIndex(wDevID)])
...
...
@@ -136,8 +164,9 @@ HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl);
BOOL16
WINAPI
mmThreadIsValid16
(
HANDLE16
hndl
);
BOOL16
WINAPI
mmThreadIsCurrent16
(
HANDLE16
hndl
);
BOOL
MULTIMEDIA_MMTimeInit
(
void
);
BOOL
MULTIMEDIA_MciInit
(
void
);
LPWINE_MM_IDATA
MULTIMEDIA_GetIData
(
void
);
BOOL
MULTIMEDIA_MidiInit
(
void
);
#endif
/* __WINE_MULTIMEDIA_H */
This diff is collapsed.
Click to expand it.
multimedia/time.c
+
75
−
71
View file @
bba54db0
...
...
@@ -6,36 +6,17 @@
* Copyright 1993 Martin Ayotte
*/
#include
<stdlib.h>
#include
<time.h>
#include
<sys/time.h>
#include
"winbase.h"
#include
"wine/winbase16.h"
/* GetTaskDS */
#include
"callback.h"
#include
"m
msystem
.h"
#include
"m
ultimedia
.h"
#include
"services.h"
#include
"syslevel.h"
#include
"debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
mmtime
)
typedef
struct
tagTIMERENTRY
{
UINT
wDelay
;
UINT
wResol
;
FARPROC16
lpFunc
;
HINSTANCE
hInstance
;
DWORD
dwUser
;
UINT
wFlags
;
UINT
wTimerID
;
UINT
wCurTime
;
UINT
isWin32
;
struct
tagTIMERENTRY
*
lpNext
;
}
TIMERENTRY
,
*
LPTIMERENTRY
;
static
DWORD
mmSysTimeMS
;
static
LPTIMERENTRY
lpTimerList
=
NULL
;
static
HANDLE
hMMTimer
=
0
;
CRITICAL_SECTION
mmTimeCritSect
;
/*
* FIXME
* We're using "1" as the mininum resolution to the timer,
...
...
@@ -51,7 +32,6 @@ static void TIME_TriggerCallBack(LPTIMERENTRY lpTimer, DWORD dwCurrent)
TRACE
(
"before CallBack (%lu)!
\n
"
,
dwCurrent
);
TRACE
(
"lpFunc=%p wTimerID=%04X dwUser=%08lX !
\n
"
,
lpTimer
->
lpFunc
,
lpTimer
->
wTimerID
,
lpTimer
->
dwUser
);
TRACE
(
"hInstance=%04X !
\n
"
,
lpTimer
->
hInstance
);
/* - TimeProc callback that is called here is something strange, under Windows 3.1x it is called
* during interrupt time, is allowed to execute very limited number of API calls (like
...
...
@@ -84,19 +64,31 @@ static void TIME_TriggerCallBack(LPTIMERENTRY lpTimer, DWORD dwCurrent)
/**************************************************************************
* TIME_MMSysTimeCallback
*/
static
void
CALLBACK
TIME_MMSysTimeCallback
(
ULONG_PTR
dummy
)
static
void
CALLBACK
TIME_MMSysTimeCallback
(
ULONG_PTR
ptr_
)
{
LPTIMERENTRY
lpTimer
,
lpNextTimer
;
mmSysTimeMS
+=
MMSYSTIME_MININTERVAL
;
EnterCriticalSection
(
&
mmTimeCritSect
);
LPTIMERENTRY
lpTimer
,
lpNextTimer
;
LPWINE_MM_IDATA
iData
=
(
LPWINE_MM_IDATA
)
ptr_
;
iData
->
mmSysTimeMS
+=
MMSYSTIME_MININTERVAL
;
/* this is a hack...
* since timeSetEvent() and timeKillEvent() can be called
* from 16 bit code, there are cases where win16 lock is
* locked upon entering timeSetEvent(), and then the process
* heap is locked. OTOH, in this callback the process heap
* is first locked, and the win16 lock can be locked while
* calling a client callback. to avoid deadlocks, the process
* heap and win 16 lock must always be locked in the same
* order...
*/
SYSLEVEL_EnterWin16Lock
();
EnterCriticalSection
(
&
iData
->
cs
);
for
(
lpTimer
=
lpTimerList
;
lpTimer
!=
NULL
;
)
{
for
(
lpTimer
=
iData
->
lpTimerList
;
lpTimer
!=
NULL
;
)
{
lpNextTimer
=
lpTimer
->
lpNext
;
if
(
lpTimer
->
wCurTime
<
MMSYSTIME_MININTERVAL
)
{
lpTimer
->
wCurTime
=
lpTimer
->
wDelay
;
TIME_TriggerCallBack
(
lpTimer
,
mmSysTimeMS
);
TIME_TriggerCallBack
(
lpTimer
,
iData
->
mmSysTimeMS
);
if
(
lpTimer
->
wFlags
&
TIME_ONESHOT
)
timeKillEvent
(
lpTimer
->
wTimerID
);
}
else
{
...
...
@@ -105,35 +97,36 @@ static void CALLBACK TIME_MMSysTimeCallback( ULONG_PTR dummy )
lpTimer
=
lpNextTimer
;
}
LeaveCriticalSection
(
&
mmTimeCritSect
);
}
/**************************************************************************
* MULTIMEDIA_MMTimeInit [internal]
*/
BOOL
MULTIMEDIA_MMTimeInit
(
void
)
{
InitializeCriticalSection
(
&
mmTimeCritSect
);
MakeCriticalSectionGlobal
(
&
mmTimeCritSect
);
return
TRUE
;
LeaveCriticalSection
(
&
iData
->
cs
);
SYSLEVEL_LeaveWin16Lock
();
}
/**************************************************************************
* MULTIMEDIA_MMTimeStart [internal]
*/
static
BOOL
MULTIMEDIA_MMTimeStart
(
void
)
static
LPWINE_MM_IDATA
MULTIMEDIA_MMTimeStart
(
void
)
{
LPWINE_MM_IDATA
iData
=
MULTIMEDIA_GetIData
();
if
(
!
iData
||
IsBadWritePtr
(
iData
,
sizeof
(
WINE_MM_IDATA
)))
{
ERR
(
"iData is not correctly set, please report. Expect failure.
\n
"
);
return
0
;
}
/* FIXME: the service timer is never killed, even when process is
* detached from this DLL
*/
/* one could think it's possible to stop the service thread activity when no more
* mm timers are active, but this would require to
handle delta (in time) between
*
GetTickCount() and timeGetTime() which are not -currently- synchronized
.
* mm timers are active, but this would require to
keep mmSysTimeMS up-to-date
*
without being incremented within the service thread callback
.
*/
if
(
!
hMMTimer
)
{
mmSysTimeMS
=
GetTickCount
();
hMMTimer
=
SERVICE_AddTimer
(
MMSYSTIME_MININTERVAL
*
1000L
,
TIME_MMSysTimeCallback
,
0
);
if
(
!
iData
->
hMMTimer
)
{
iData
->
mmSysTimeMS
=
GetTickCount
();
iData
->
lpTimerList
=
NULL
;
iData
->
hMMTimer
=
SERVICE_AddTimer
(
MMSYSTIME_MININTERVAL
*
1000L
,
TIME_MMSysTimeCallback
,
(
DWORD
)
iData
);
InitializeCriticalSection
(
&
iData
->
cs
);
}
return
TRUE
;
return
iData
;
}
/**************************************************************************
...
...
@@ -141,14 +134,18 @@ static BOOL MULTIMEDIA_MMTimeStart(void)
*/
MMRESULT
WINAPI
timeGetSystemTime
(
LPMMTIME
lpTime
,
UINT
wSize
)
{
LPWINE_MM_IDATA
iData
;
TRACE
(
"(%p, %u);
\n
"
,
lpTime
,
wSize
);
if
(
wSize
>=
sizeof
(
*
lpTime
))
{
MULTIMEDIA_MMTimeStart
();
iData
=
MULTIMEDIA_MMTimeStart
();
if
(
!
iData
)
return
MMSYSERR_NOMEM
;
lpTime
->
wType
=
TIME_MS
;
lpTime
->
u
.
ms
=
mmSysTimeMS
;
lpTime
->
u
.
ms
=
iData
->
mmSysTimeMS
;
TRACE
(
"=> %lu
\n
"
,
mmSysTimeMS
);
TRACE
(
"=> %lu
\n
"
,
iData
->
mmSysTimeMS
);
}
return
0
;
...
...
@@ -159,14 +156,18 @@ MMRESULT WINAPI timeGetSystemTime(LPMMTIME lpTime, UINT wSize)
*/
MMRESULT16
WINAPI
timeGetSystemTime16
(
LPMMTIME16
lpTime
,
UINT16
wSize
)
{
LPWINE_MM_IDATA
iData
;
TRACE
(
"(%p, %u);
\n
"
,
lpTime
,
wSize
);
if
(
wSize
>=
sizeof
(
*
lpTime
))
{
MULTIMEDIA_MMTimeStart
();
iData
=
MULTIMEDIA_MMTimeStart
();
if
(
!
iData
)
return
MMSYSERR_NOMEM
;
lpTime
->
wType
=
TIME_MS
;
lpTime
->
u
.
ms
=
mmSysTimeMS
;
lpTime
->
u
.
ms
=
iData
->
mmSysTimeMS
;
TRACE
(
"=> %lu
\n
"
,
mmSysTimeMS
);
TRACE
(
"=> %lu
\n
"
,
iData
->
mmSysTimeMS
);
}
return
0
;
...
...
@@ -182,37 +183,40 @@ static WORD timeSetEventInternal(UINT wDelay, UINT wResol,
WORD
wNewID
=
0
;
LPTIMERENTRY
lpNewTimer
;
LPTIMERENTRY
lpTimer
;
LPWINE_MM_IDATA
iData
;
TRACE
(
"(%u, %u, %p, %08lX, %04X);
\n
"
,
wDelay
,
wResol
,
lpFunc
,
dwUser
,
wFlags
);
lpNewTimer
=
(
LPTIMERENTRY
)
malloc
(
sizeof
(
TIMERENTRY
));
lpNewTimer
=
(
LPTIMERENTRY
)
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
TIMERENTRY
));
if
(
lpNewTimer
==
NULL
)
return
0
;
MULTIMEDIA_MMTimeStart
();
iData
=
MULTIMEDIA_MMTimeStart
();
if
(
!
iData
)
return
0
;
lpNewTimer
->
wCurTime
=
wDelay
;
lpNewTimer
->
wDelay
=
wDelay
;
lpNewTimer
->
wResol
=
wResol
;
lpNewTimer
->
lpFunc
=
lpFunc
;
lpNewTimer
->
isWin32
=
isWin32
;
lpNewTimer
->
hInstance
=
GetTaskDS16
();
lpNewTimer
->
dwUser
=
dwUser
;
lpNewTimer
->
wFlags
=
wFlags
;
TRACE
(
"
hInstance=%04X,
lpFunc=0x%08lx !
\n
"
,
lpNewTimer
->
hInstance
,
(
DWORD
)
lpFunc
);
TRACE
(
"lpFunc=0x%08lx !
\n
"
,
(
DWORD
)
lpFunc
);
EnterCriticalSection
(
&
mmTimeCritSect
);
EnterCriticalSection
(
&
iData
->
cs
);
for
(
lpTimer
=
lpTimerList
;
lpTimer
!=
NULL
;
lpTimer
=
lpTimer
->
lpNext
)
{
for
(
lpTimer
=
iData
->
lpTimerList
;
lpTimer
!=
NULL
;
lpTimer
=
lpTimer
->
lpNext
)
{
wNewID
=
MAX
(
wNewID
,
lpTimer
->
wTimerID
);
}
lpNewTimer
->
lpNext
=
lpTimerList
;
lpTimerList
=
lpNewTimer
;
lpNewTimer
->
lpNext
=
iData
->
lpTimerList
;
iData
->
lpTimerList
=
lpNewTimer
;
lpNewTimer
->
wTimerID
=
wNewID
+
1
;
LeaveCriticalSection
(
&
mmTimeCritSect
);
LeaveCriticalSection
(
&
iData
->
cs
);
return
wNewID
+
1
;
}
...
...
@@ -241,22 +245,23 @@ MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol, LPTIMECALLBACK16
MMRESULT
WINAPI
timeKillEvent
(
UINT
wID
)
{
LPTIMERENTRY
*
lpTimer
;
LPWINE_MM_IDATA
iData
=
MULTIMEDIA_GetIData
();
MMRESULT
ret
=
MMSYSERR_INVALPARAM
;
EnterCriticalSection
(
&
mmTimeCritSect
);
EnterCriticalSection
(
&
iData
->
cs
);
for
(
lpTimer
=
&
lpTimerList
;
*
lpTimer
;
lpTimer
=
&
((
*
lpTimer
)
->
lpNext
))
{
for
(
lpTimer
=
&
iData
->
lpTimerList
;
*
lpTimer
;
lpTimer
=
&
((
*
lpTimer
)
->
lpNext
))
{
if
(
wID
==
(
*
lpTimer
)
->
wTimerID
)
{
LPTIMERENTRY
xlptimer
=
(
*
lpTimer
)
->
lpNext
;
free
(
*
lpTimer
);
HeapFree
(
GetProcessHeap
(),
0
,
*
lpTimer
);
*
lpTimer
=
xlptimer
;
ret
=
TIMERR_NOERROR
;
break
;
}
}
LeaveCriticalSection
(
&
mmTimeCritSect
);
LeaveCriticalSection
(
&
iData
->
cs
);
return
ret
;
}
...
...
@@ -346,6 +351,5 @@ MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
*/
DWORD
WINAPI
timeGetTime
(
void
)
{
MULTIMEDIA_MMTimeStart
();
return
mmSysTimeMS
;
return
MULTIMEDIA_MMTimeStart
()
->
mmSysTimeMS
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment