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
844dbd2e
Commit
844dbd2e
authored
Dec 02, 2020
by
Shen-Ta Hsieh
Committed by
Max Kellermann
Mar 04, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
src/output: Use WinEvent for as a condition_variable without lock
parent
db7caa2d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
14 additions
and
23 deletions
+14
-23
WasapiOutputPlugin.cxx
src/output/plugins/WasapiOutputPlugin.cxx
+14
-23
No files found.
src/output/plugins/WasapiOutputPlugin.cxx
View file @
844dbd2e
...
...
@@ -129,15 +129,11 @@ public:
void
Finish
()
noexcept
{
return
SetStatus
(
Status
::
FINISH
);
}
void
Play
()
noexcept
{
return
SetStatus
(
Status
::
PLAY
);
}
void
Pause
()
noexcept
{
return
SetStatus
(
Status
::
PAUSE
);
}
void
WaitWrite
()
noexcept
{
std
::
unique_lock
<
Mutex
>
lock
(
write
.
mutex
);
write
.
cond
.
wait
(
lock
);
}
void
WaitDataPoped
()
noexcept
{
data_poped
.
Wait
(
200
);
}
void
CheckException
()
{
std
::
unique_lock
<
Mutex
>
lock
(
error
.
mutex
);
if
(
error
.
error_ptr
)
{
std
::
exception_ptr
err
=
std
::
exchange
(
error
.
error_ptr
,
nullptr
);
error
.
cond
.
notify_all
();
if
(
error
.
occur
.
load
())
{
auto
err
=
std
::
exchange
(
error
.
ptr
,
nullptr
);
error
.
thrown
.
Set
();
std
::
rethrow_exception
(
err
);
}
}
...
...
@@ -145,6 +141,7 @@ public:
private
:
friend
class
WasapiOutput
;
WinEvent
event
;
WinEvent
data_poped
;
IAudioClient
*
client
;
ComPtr
<
IAudioRenderClient
>
render_client
;
const
UINT32
frame_size
;
...
...
@@ -153,14 +150,10 @@ private:
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
std
::
atomic
<
Status
>
status
=
Status
::
PAUSE
;
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
struct
{
Mutex
mutex
;
Cond
cond
;
}
write
{};
alignas
(
BOOST_LOCKFREE_CACHELINE_BYTES
)
struct
{
Mutex
mutex
;
Cond
cond
;
std
::
exception_ptr
error_ptr
=
nullptr
;
}
error
{};
std
::
atomic_bool
occur
=
false
;
std
::
exception_ptr
ptr
=
nullptr
;
WinEvent
thrown
;
}
error
;
boost
::
lockfree
::
spsc_queue
<
BYTE
>
spsc_buffer
;
void
SetStatus
(
Status
s
)
noexcept
{
...
...
@@ -255,8 +248,6 @@ void WasapiOutputThread::Work() noexcept {
return
;
}
AtScopeExit
(
&
)
{
write
.
cond
.
notify_all
();
};
HRESULT
result
;
UINT32
data_in_frames
;
result
=
client
->
GetCurrentPadding
(
&
data_in_frames
);
...
...
@@ -293,16 +284,16 @@ void WasapiOutputThread::Work() noexcept {
new_data_size
=
spsc_buffer
.
pop
(
data
,
write_size
);
std
::
fill_n
(
data
+
new_data_size
,
write_size
-
new_data_size
,
0
);
data_poped
.
Set
();
}
else
{
mode
=
AUDCLNT_BUFFERFLAGS_SILENT
;
FormatDebug
(
wasapi_output_domain
,
"Working thread paused"
);
}
}
catch
(...)
{
std
::
unique_lock
<
Mutex
>
lock
(
error
.
mutex
);
error
.
error_ptr
=
std
::
current_exception
();
error
.
cond
.
wait
(
lock
);
assert
(
error
.
error_ptr
==
nullptr
);
error
.
ptr
=
std
::
current_exception
();
error
.
occur
.
store
(
true
);
error
.
thrown
.
Wait
(
INFINITE
);
}
}
}
...
...
@@ -491,7 +482,7 @@ size_t WasapiOutput::Play(const void *chunk, size_t size) {
thread
->
spsc_buffer
.
push
(
static_cast
<
const
BYTE
*>
(
chunk
),
size
);
if
(
consumed_size
==
0
)
{
assert
(
is_started
);
thread
->
Wait
Write
();
thread
->
Wait
DataPoped
();
continue
;
}
...
...
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