player/Control: pass std::unique_lock<> to Cond::wait()
This commit is contained in:
parent
cf348f9fae
commit
dedc4b4b10
@ -45,11 +45,12 @@ PlayerControl::~PlayerControl() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlayerControl::WaitOutputConsumed(unsigned threshold) noexcept
|
PlayerControl::WaitOutputConsumed(std::unique_lock<Mutex> &lock,
|
||||||
|
unsigned threshold) noexcept
|
||||||
{
|
{
|
||||||
bool result = outputs.CheckPipe() < threshold;
|
bool result = outputs.CheckPipe() < threshold;
|
||||||
if (!result && command == PlayerCommand::NONE) {
|
if (!result && command == PlayerCommand::NONE) {
|
||||||
Wait();
|
Wait(lock);
|
||||||
result = outputs.CheckPipe() < threshold;
|
result = outputs.CheckPipe() < threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,13 +65,13 @@ PlayerControl::Play(std::unique_ptr<DetachedSong> song)
|
|||||||
|
|
||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
SeekLocked(std::move(song), SongTime::zero());
|
SeekLocked(lock, std::move(song), SongTime::zero());
|
||||||
|
|
||||||
if (state == PlayerState::PAUSE)
|
if (state == PlayerState::PAUSE)
|
||||||
/* if the player was paused previously, we need to
|
/* if the player was paused previously, we need to
|
||||||
unpause it */
|
unpause it */
|
||||||
PauseLocked();
|
PauseLocked(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -116,10 +117,10 @@ PlayerControl::Kill() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayerControl::PauseLocked() noexcept
|
PlayerControl::PauseLocked(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
if (state != PlayerState::STOP) {
|
if (state != PlayerState::STOP) {
|
||||||
SynchronousCommand(PlayerCommand::PAUSE);
|
SynchronousCommand(lock, PlayerCommand::PAUSE);
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,8 +128,8 @@ PlayerControl::PauseLocked() noexcept
|
|||||||
void
|
void
|
||||||
PlayerControl::LockPause() noexcept
|
PlayerControl::LockPause() noexcept
|
||||||
{
|
{
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
PauseLocked();
|
PauseLocked(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -137,7 +138,7 @@ PlayerControl::LockSetPause(bool pause_flag) noexcept
|
|||||||
if (!thread.IsDefined())
|
if (!thread.IsDefined())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PlayerState::STOP:
|
case PlayerState::STOP:
|
||||||
@ -145,12 +146,12 @@ PlayerControl::LockSetPause(bool pause_flag) noexcept
|
|||||||
|
|
||||||
case PlayerState::PLAY:
|
case PlayerState::PLAY:
|
||||||
if (pause_flag)
|
if (pause_flag)
|
||||||
PauseLocked();
|
PauseLocked(lock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerState::PAUSE:
|
case PlayerState::PAUSE:
|
||||||
if (!pause_flag)
|
if (!pause_flag)
|
||||||
PauseLocked();
|
PauseLocked(lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,9 +168,9 @@ PlayerControl::LockGetStatus() noexcept
|
|||||||
{
|
{
|
||||||
PlayerStatus status;
|
PlayerStatus status;
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
if (!occupied && thread.IsDefined())
|
if (!occupied && thread.IsDefined())
|
||||||
SynchronousCommand(PlayerCommand::REFRESH);
|
SynchronousCommand(lock, PlayerCommand::REFRESH);
|
||||||
|
|
||||||
status.state = state;
|
status.state = state;
|
||||||
|
|
||||||
@ -233,23 +234,25 @@ PlayerControl::LockEnqueueSong(std::unique_ptr<DetachedSong> song) noexcept
|
|||||||
assert(thread.IsDefined());
|
assert(thread.IsDefined());
|
||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
EnqueueSongLocked(std::move(song));
|
EnqueueSongLocked(lock, std::move(song));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayerControl::EnqueueSongLocked(std::unique_ptr<DetachedSong> song) noexcept
|
PlayerControl::EnqueueSongLocked(std::unique_lock<Mutex> &lock,
|
||||||
|
std::unique_ptr<DetachedSong> song) noexcept
|
||||||
{
|
{
|
||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
next_song = std::move(song);
|
next_song = std::move(song);
|
||||||
seek_time = SongTime::zero();
|
seek_time = SongTime::zero();
|
||||||
SynchronousCommand(PlayerCommand::QUEUE);
|
SynchronousCommand(lock, PlayerCommand::QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayerControl::SeekLocked(std::unique_ptr<DetachedSong> song, SongTime t)
|
PlayerControl::SeekLocked(std::unique_lock<Mutex> &lock,
|
||||||
|
std::unique_ptr<DetachedSong> song, SongTime t)
|
||||||
{
|
{
|
||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
|
|
||||||
@ -258,21 +261,21 @@ PlayerControl::SeekLocked(std::unique_ptr<DetachedSong> song, SongTime t)
|
|||||||
/* optimization TODO: if the decoder happens to decode that
|
/* optimization TODO: if the decoder happens to decode that
|
||||||
song already, don't cancel that */
|
song already, don't cancel that */
|
||||||
if (next_song != nullptr)
|
if (next_song != nullptr)
|
||||||
SynchronousCommand(PlayerCommand::CANCEL);
|
SynchronousCommand(lock, PlayerCommand::CANCEL);
|
||||||
|
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
ClearError();
|
ClearError();
|
||||||
next_song = std::move(song);
|
next_song = std::move(song);
|
||||||
seek_time = t;
|
seek_time = t;
|
||||||
SynchronousCommand(PlayerCommand::SEEK);
|
SynchronousCommand(lock, PlayerCommand::SEEK);
|
||||||
|
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
/* the SEEK command is asynchronous; until completion, the
|
/* the SEEK command is asynchronous; until completion, the
|
||||||
"seeking" flag is set */
|
"seeking" flag is set */
|
||||||
while (seeking)
|
while (seeking)
|
||||||
ClientWait();
|
ClientWait(lock);
|
||||||
|
|
||||||
if (error_type != PlayerError::NONE) {
|
if (error_type != PlayerError::NONE) {
|
||||||
assert(error);
|
assert(error);
|
||||||
@ -290,8 +293,8 @@ PlayerControl::LockSeek(std::unique_ptr<DetachedSong> song, SongTime t)
|
|||||||
|
|
||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
SeekLocked(std::move(song), t);
|
SeekLocked(lock, std::move(song), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -368,10 +368,10 @@ private:
|
|||||||
* valid in the player thread. The object must be locked
|
* valid in the player thread. The object must be locked
|
||||||
* prior to calling this function.
|
* prior to calling this function.
|
||||||
*/
|
*/
|
||||||
void Wait() noexcept {
|
void Wait(std::unique_lock<Mutex> &lock) noexcept {
|
||||||
assert(thread.IsInside());
|
assert(thread.IsInside());
|
||||||
|
|
||||||
cond.wait(mutex);
|
cond.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,10 +391,10 @@ private:
|
|||||||
*
|
*
|
||||||
* Caller must lock the object.
|
* Caller must lock the object.
|
||||||
*/
|
*/
|
||||||
void ClientWait() noexcept {
|
void ClientWait(std::unique_lock<Mutex> &lock) noexcept {
|
||||||
assert(!thread.IsInside());
|
assert(!thread.IsInside());
|
||||||
|
|
||||||
client_cond.wait(mutex);
|
client_cond.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,11 +426,12 @@ private:
|
|||||||
* @param threshold the maximum number of chunks in the pipe
|
* @param threshold the maximum number of chunks in the pipe
|
||||||
* @return true if there are less than #threshold chunks in the pipe
|
* @return true if there are less than #threshold chunks in the pipe
|
||||||
*/
|
*/
|
||||||
bool WaitOutputConsumed(unsigned threshold) noexcept;
|
bool WaitOutputConsumed(std::unique_lock<Mutex> &lock,
|
||||||
|
unsigned threshold) noexcept;
|
||||||
|
|
||||||
bool LockWaitOutputConsumed(unsigned threshold) noexcept {
|
bool LockWaitOutputConsumed(unsigned threshold) noexcept {
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
return WaitOutputConsumed(threshold);
|
return WaitOutputConsumed(lock, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -439,9 +440,9 @@ private:
|
|||||||
* To be called from the main thread. Caller must lock the
|
* To be called from the main thread. Caller must lock the
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void WaitCommandLocked() noexcept {
|
void WaitCommandLocked(std::unique_lock<Mutex> &lock) noexcept {
|
||||||
while (command != PlayerCommand::NONE)
|
while (command != PlayerCommand::NONE)
|
||||||
ClientWait();
|
ClientWait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -451,12 +452,13 @@ private:
|
|||||||
* To be called from the main thread. Caller must lock the
|
* To be called from the main thread. Caller must lock the
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void SynchronousCommand(PlayerCommand cmd) noexcept {
|
void SynchronousCommand(std::unique_lock<Mutex> &lock,
|
||||||
|
PlayerCommand cmd) noexcept {
|
||||||
assert(command == PlayerCommand::NONE);
|
assert(command == PlayerCommand::NONE);
|
||||||
|
|
||||||
command = cmd;
|
command = cmd;
|
||||||
Signal();
|
Signal();
|
||||||
WaitCommandLocked();
|
WaitCommandLocked(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -467,11 +469,11 @@ private:
|
|||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void LockSynchronousCommand(PlayerCommand cmd) noexcept {
|
void LockSynchronousCommand(PlayerCommand cmd) noexcept {
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
SynchronousCommand(cmd);
|
SynchronousCommand(lock, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PauseLocked() noexcept;
|
void PauseLocked(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
void ClearError() noexcept {
|
void ClearError() noexcept {
|
||||||
error_type = PlayerError::NONE;
|
error_type = PlayerError::NONE;
|
||||||
@ -535,12 +537,14 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::unique_ptr<DetachedSong> ReadTaggedSong() noexcept;
|
std::unique_ptr<DetachedSong> ReadTaggedSong() noexcept;
|
||||||
|
|
||||||
void EnqueueSongLocked(std::unique_ptr<DetachedSong> song) noexcept;
|
void EnqueueSongLocked(std::unique_lock<Mutex> &lock,
|
||||||
|
std::unique_ptr<DetachedSong> song) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws on error.
|
* Throws on error.
|
||||||
*/
|
*/
|
||||||
void SeekLocked(std::unique_ptr<DetachedSong> song, SongTime t);
|
void SeekLocked(std::unique_lock<Mutex> &lock,
|
||||||
|
std::unique_ptr<DetachedSong> song, SongTime t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller must lock the object.
|
* Caller must lock the object.
|
||||||
|
@ -515,7 +515,7 @@ Player::CheckDecoderStartup(std::unique_lock<Mutex> &lock) noexcept
|
|||||||
/* the decoder is ready and ok */
|
/* the decoder is ready and ok */
|
||||||
|
|
||||||
if (output_open &&
|
if (output_open &&
|
||||||
!pc.WaitOutputConsumed(1))
|
!pc.WaitOutputConsumed(lock, 1))
|
||||||
/* the output devices havn't finished playing
|
/* the output devices havn't finished playing
|
||||||
all chunks yet - wait for that */
|
all chunks yet - wait for that */
|
||||||
return true;
|
return true;
|
||||||
@ -1037,7 +1037,7 @@ Player::Run() noexcept
|
|||||||
|
|
||||||
if (paused) {
|
if (paused) {
|
||||||
if (pc.command == PlayerCommand::NONE)
|
if (pc.command == PlayerCommand::NONE)
|
||||||
pc.Wait();
|
pc.Wait(lock);
|
||||||
} else if (!pipe->IsEmpty()) {
|
} else if (!pipe->IsEmpty()) {
|
||||||
/* at least one music chunk is ready - send it
|
/* at least one music chunk is ready - send it
|
||||||
to the audio output */
|
to the audio output */
|
||||||
@ -1128,7 +1128,7 @@ try {
|
|||||||
|
|
||||||
MusicBuffer buffer(buffer_chunks);
|
MusicBuffer buffer(buffer_chunks);
|
||||||
|
|
||||||
const std::lock_guard<Mutex> lock(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
@ -1201,7 +1201,7 @@ try {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerCommand::NONE:
|
case PlayerCommand::NONE:
|
||||||
Wait();
|
Wait(lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user