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
d5e156fa
Commit
d5e156fa
authored
Oct 16, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Oct 17, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dmime: Rewrite message thread with a condition variable.
parent
48aa9031
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
72 deletions
+33
-72
performance.c
dlls/dmime/performance.c
+33
-72
No files found.
dlls/dmime/performance.c
View file @
d5e156fa
...
...
@@ -54,11 +54,10 @@ struct performance
REFERENCE_TIME
rtLatencyTime
;
DWORD
dwBumperLength
;
DWORD
dwPrepareTime
;
/** Message Processing */
HANDLE
procThread
;
DWORD
procThreadId
;
BOOL
procThreadTicStarted
;
HANDLE
message_thread
;
CRITICAL_SECTION
safe
;
CONDITION_VARIABLE
cond
;
IReferenceClock
*
master_clock
;
REFERENCE_TIME
init_time
;
...
...
@@ -124,25 +123,20 @@ static HRESULT performance_process_message(struct performance *This, DMUS_PMSG *
return
hr
;
}
#define PROCESSMSG_START (WM_APP + 0)
#define PROCESSMSG_EXIT (WM_APP + 1)
#define PROCESSMSG_REMOVE (WM_APP + 2)
#define PROCESSMSG_ADD (WM_APP + 4)
static
DWORD
WINAPI
ProcessMsgThread
(
LPVOID
lpParam
)
static
DWORD
WINAPI
message_thread_proc
(
void
*
args
)
{
struct
performance
*
This
=
lpParam
;
DWORD
timeout
=
INFINITE
;
MSG
msg
;
HRESULT
hr
;
struct
performance
*
This
=
args
;
struct
message
*
message
,
*
next
;
HRESULT
hr
;
while
(
TRUE
)
{
if
(
timeout
>
0
)
MsgWaitForMultipleObjects
(
0
,
NULL
,
FALSE
,
timeout
,
QS_POSTMESSAGE
|
QS_SENDMESSAGE
|
QS_TIMER
);
timeout
=
INFINITE
;
TRACE
(
"performance %p message thread
\n
"
,
This
);
SetThreadDescription
(
GetCurrentThread
(),
L"wine_dmime_message"
);
EnterCriticalSection
(
&
This
->
safe
);
EnterCriticalSection
(
&
This
->
safe
);
while
(
This
->
message_thread
)
{
DWORD
timeout
=
INFINITE
;
LIST_FOR_EACH_ENTRY_SAFE
(
message
,
next
,
&
This
->
messages
,
struct
message
,
entry
)
{
...
...
@@ -154,59 +148,15 @@ static DWORD WINAPI ProcessMsgThread(LPVOID lpParam)
if
(
hr
!=
S_OK
)
break
;
}
LeaveCriticalSection
(
&
This
->
safe
);
while
(
PeekMessageA
(
&
msg
,
NULL
,
0
,
0
,
PM_REMOVE
))
{
/** if hwnd we suppose that is a windows event ... */
if
(
NULL
!=
msg
.
hwnd
)
{
TranslateMessage
(
&
msg
);
DispatchMessageA
(
&
msg
);
}
else
{
switch
(
msg
.
message
)
{
case
WM_QUIT
:
case
PROCESSMSG_EXIT
:
goto
outofthread
;
case
PROCESSMSG_START
:
break
;
case
PROCESSMSG_ADD
:
break
;
case
PROCESSMSG_REMOVE
:
break
;
default:
ERR
(
"Unhandled message %u. Critical Path
\n
"
,
msg
.
message
);
break
;
}
}
}
/** here we should run a little of current AudioPath */
SleepConditionVariableCS
(
&
This
->
cond
,
&
This
->
safe
,
timeout
);
}
outofthread:
TRACE
(
"(%p): Exiting
\n
"
,
This
);
LeaveCriticalSection
(
&
This
->
safe
);
TRACE
(
"(%p): Exiting
\n
"
,
This
);
return
0
;
}
static
BOOL
PostMessageToProcessMsgThread
(
struct
performance
*
This
,
UINT
iMsg
)
{
if
(
FALSE
==
This
->
procThreadTicStarted
&&
PROCESSMSG_EXIT
!=
iMsg
)
{
BOOL
res
;
This
->
procThread
=
CreateThread
(
NULL
,
0
,
ProcessMsgThread
,
This
,
0
,
&
This
->
procThreadId
);
if
(
NULL
==
This
->
procThread
)
return
FALSE
;
SetThreadPriority
(
This
->
procThread
,
THREAD_PRIORITY_TIME_CRITICAL
);
This
->
procThreadTicStarted
=
TRUE
;
while
(
1
)
{
res
=
PostThreadMessageA
(
This
->
procThreadId
,
iMsg
,
0
,
0
);
/* Let the thread creates its message queue (with MsgWaitForMultipleObjects call) by yielding and retrying */
if
(
!
res
&&
(
GetLastError
()
==
ERROR_INVALID_THREAD_ID
))
Sleep
(
0
);
else
break
;
}
return
res
;
}
return
PostThreadMessageA
(
This
->
procThreadId
,
iMsg
,
0
,
0
);
}
static
HRESULT
performance_send_dirty_pmsg
(
struct
performance
*
This
,
MUSIC_TIME
music_time
)
{
IDirectMusicPerformance8
*
performance
=
&
This
->
IDirectMusicPerformance8_iface
;
...
...
@@ -424,7 +374,12 @@ static HRESULT WINAPI performance_Init(IDirectMusicPerformance8 *iface, IDirectM
return
hr
;
}
PostMessageToProcessMsgThread
(
This
,
PROCESSMSG_START
);
if
(
!
(
This
->
message_thread
=
CreateThread
(
NULL
,
0
,
message_thread_proc
,
This
,
0
,
NULL
)))
{
ERR
(
"Failed to start performance message thread, error %lu
\n
"
,
GetLastError
());
IDirectMusicPerformance_CloseDown
(
iface
);
return
HRESULT_FROM_WIN32
(
GetLastError
());
}
if
(
dmusic
&&
!*
dmusic
)
{
...
...
@@ -549,13 +504,13 @@ static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS
LIST_FOR_EACH_ENTRY
(
next
,
&
This
->
messages
,
struct
message
,
entry
)
if
(
next
->
msg
.
rtTime
>
message
->
msg
.
rtTime
)
break
;
list_add_before
(
&
next
->
entry
,
&
message
->
entry
);
PostThreadMessageW
(
This
->
procThreadId
,
PROCESSMSG_ADD
,
0
,
0
);
hr
=
S_OK
;
}
done:
LeaveCriticalSection
(
&
This
->
safe
);
if
(
SUCCEEDED
(
hr
))
WakeConditionVariable
(
&
This
->
cond
);
return
hr
;
}
...
...
@@ -1033,14 +988,20 @@ static HRESULT WINAPI performance_CloseDown(IDirectMusicPerformance8 *iface)
{
struct
performance
*
This
=
impl_from_IDirectMusicPerformance8
(
iface
);
struct
message
*
message
,
*
next
;
HANDLE
message_thread
;
HRESULT
hr
;
FIXME
(
"(%p): semi-stub
\n
"
,
This
);
if
(
PostMessageToProcessMsgThread
(
This
,
PROCESSMSG_EXIT
))
{
WaitForSingleObject
(
This
->
procThread
,
INFINITE
);
This
->
procThreadTicStarted
=
FALSE
;
CloseHandle
(
This
->
procThread
);
if
((
message_thread
=
This
->
message_thread
))
{
EnterCriticalSection
(
&
This
->
safe
);
This
->
message_thread
=
NULL
;
LeaveCriticalSection
(
&
This
->
safe
);
WakeConditionVariable
(
&
This
->
cond
);
WaitForSingleObject
(
message_thread
,
INFINITE
);
CloseHandle
(
message_thread
);
}
This
->
notification_performance
=
FALSE
;
...
...
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