player/Control: add "occupied" flag to skip REFRESH
Reduces main thread contention. Avoids blocking the main thread in "status" commands.
This commit is contained in:
@@ -44,6 +44,7 @@ PlayerControl::PlayerControl(PlayerListener &_listener,
|
|||||||
|
|
||||||
PlayerControl::~PlayerControl() noexcept
|
PlayerControl::~PlayerControl() noexcept
|
||||||
{
|
{
|
||||||
|
assert(!occupied);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -155,7 +156,8 @@ PlayerControl::LockGetStatus() noexcept
|
|||||||
player_status status;
|
player_status status;
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
const std::lock_guard<Mutex> protect(mutex);
|
||||||
SynchronousCommand(PlayerCommand::REFRESH);
|
if (!occupied)
|
||||||
|
SynchronousCommand(PlayerCommand::REFRESH);
|
||||||
|
|
||||||
status.state = state;
|
status.state = state;
|
||||||
|
|
||||||
|
@@ -185,6 +185,29 @@ struct PlayerControl final : AudioOutputClient {
|
|||||||
*/
|
*/
|
||||||
bool border_pause = false;
|
bool border_pause = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this flag is set, then the player thread is currently
|
||||||
|
* occupied and will not be able to respond quickly to
|
||||||
|
* commands (e.g. waiting for the decoder thread to finish
|
||||||
|
* seeking). This is used to skip #PlayerCommand::REFRESH to
|
||||||
|
* avoid blocking the main thread.
|
||||||
|
*/
|
||||||
|
bool occupied = false;
|
||||||
|
|
||||||
|
struct ScopeOccupied {
|
||||||
|
PlayerControl &pc;
|
||||||
|
|
||||||
|
explicit ScopeOccupied(PlayerControl &_pc) noexcept:pc(_pc) {
|
||||||
|
assert(!pc.occupied);
|
||||||
|
pc.occupied = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopeOccupied() noexcept {
|
||||||
|
assert(pc.occupied);
|
||||||
|
pc.occupied = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
AudioFormat audio_format;
|
AudioFormat audio_format;
|
||||||
uint16_t bit_rate;
|
uint16_t bit_rate;
|
||||||
|
|
||||||
|
@@ -367,6 +367,8 @@ Player::StartDecoder(MusicPipe &_pipe) noexcept
|
|||||||
void
|
void
|
||||||
Player::StopDecoder() noexcept
|
Player::StopDecoder() noexcept
|
||||||
{
|
{
|
||||||
|
const PlayerControl::ScopeOccupied occupied(pc);
|
||||||
|
|
||||||
dc.Stop();
|
dc.Stop();
|
||||||
|
|
||||||
if (dc.pipe != nullptr) {
|
if (dc.pipe != nullptr) {
|
||||||
@@ -624,6 +626,8 @@ Player::SeekDecoder() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const PlayerControl::ScopeOccupied occupied(pc);
|
||||||
|
|
||||||
dc.Seek(where + start_time);
|
dc.Seek(where + start_time);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
/* decoder failure */
|
/* decoder failure */
|
||||||
|
Reference in New Issue
Block a user