Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
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
Иван Мажукин
mpd
Commits
1fe0c673
Commit
1fe0c673
authored
4 years ago
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/wasapi: implement Cancel() properly
Calling consume_all() is illegal in the producer thread.
parent
8a045207
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
28 additions
and
1 deletion
+28
-1
WasapiOutputPlugin.cxx
src/output/plugins/wasapi/WasapiOutputPlugin.cxx
+28
-1
No files found.
src/output/plugins/wasapi/WasapiOutputPlugin.cxx
View file @
1fe0c673
...
@@ -170,7 +170,10 @@ class WasapiOutputThread {
...
@@ -170,7 +170,10 @@ class WasapiOutputThread {
bool
started
=
false
;
bool
started
=
false
;
std
::
atomic_bool
cancel
=
false
;
enum
class
Status
:
uint32_t
{
FINISH
,
PLAY
,
PAUSE
};
enum
class
Status
:
uint32_t
{
FINISH
,
PLAY
,
PAUSE
};
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
std
::
atomic
<
Status
>
status
=
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
std
::
atomic
<
Status
>
status
=
Status
::
PAUSE
;
Status
::
PAUSE
;
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
struct
{
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
struct
{
...
@@ -202,6 +205,24 @@ public:
...
@@ -202,6 +205,24 @@ public:
void
Pause
()
noexcept
{
return
SetStatus
(
Status
::
PAUSE
);
}
void
Pause
()
noexcept
{
return
SetStatus
(
Status
::
PAUSE
);
}
/**
/**
* Instruct the thread to discard the buffer (and wait for
* completion). This needs to be done inside this thread,
* because only the consumer thread is allowed to do that.
*/
void
Cancel
()
noexcept
{
cancel
.
store
(
true
);
event
.
Set
();
while
(
cancel
.
load
()
&&
!
error
.
occur
.
load
())
Wait
();
/* not rethrowing the exception here via
CheckException() because this method must be
"noexcept"; the next WasapiOutput::Play() call will
throw */
}
/**
* Wait for the thread to finish some work (e.g. until some
* Wait for the thread to finish some work (e.g. until some
* buffer space becomes available).
* buffer space becomes available).
*/
*/
...
@@ -366,6 +387,12 @@ try {
...
@@ -366,6 +387,12 @@ try {
while
(
true
)
{
while
(
true
)
{
event
.
Wait
();
event
.
Wait
();
if
(
cancel
.
load
())
{
spsc_buffer
.
consume_all
([](
auto
&&
)
{});
cancel
.
store
(
false
);
InterruptWaiter
();
}
Status
current_state
=
status
.
load
();
Status
current_state
=
status
.
load
();
switch
(
current_state
)
{
switch
(
current_state
)
{
case
Status
:
:
FINISH
:
case
Status
:
:
FINISH
:
...
@@ -707,7 +734,7 @@ WasapiOutput::Cancel() noexcept
...
@@ -707,7 +734,7 @@ WasapiOutput::Cancel() noexcept
{
{
assert
(
thread
);
assert
(
thread
);
thread
->
spsc_buffer
.
consume_all
([](
auto
&&
)
{}
);
thread
->
Cancel
(
);
}
}
/// run inside COMWorkerThread
/// run inside COMWorkerThread
...
...
This diff is collapsed.
Click to expand it.
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