Partition: add a local idle_monitor

Make idle events per-partition, but leave Instance::EmitIdle() and its
underlying idle_monitor which broadcasts idle events to all
partitions.
This commit is contained in:
Max Kellermann 2020-01-20 13:28:58 +01:00
parent 879bafb837
commit 49309b419f
6 changed files with 32 additions and 26 deletions

View File

@ -180,10 +180,7 @@ Instance::OnRemoteTag(const char *uri, const Tag &tag) noexcept
void
Instance::OnIdle(unsigned flags) noexcept
{
/* send "idle" notifications to all subscribed
clients */
client_list->IdleAdd(flags);
if (flags & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
OnStateModified();
/* broadcast to all partitions */
for (auto &partition : partitions)
partition.EmitIdle(flags);
}

View File

@ -101,6 +101,10 @@ struct Instance final
std::unique_ptr<InputCacheManager> input_cache;
/**
* Monitor for global idle events to be broadcasted to all
* partitions.
*/
MaskMonitor idle_monitor;
#ifdef ENABLE_NEIGHBOR_PLUGINS

View File

@ -40,6 +40,7 @@ Partition::Partition(Instance &_instance,
:instance(_instance),
name(_name),
listener(new ClientListener(instance.event_loop, *this)),
idle_monitor(instance.event_loop, BIND_THIS_METHOD(OnIdleMonitor)),
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
playlist(max_length, *this),
outputs(*this),
@ -60,12 +61,6 @@ Partition::BeginShutdown() noexcept
listener.reset();
}
void
Partition::EmitIdle(unsigned mask) noexcept
{
instance.EmitIdle(mask);
}
static void
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
{
@ -215,6 +210,18 @@ Partition::OnMixerVolumeChanged(Mixer &, int) noexcept
EmitIdle(IDLE_MIXER);
}
void
Partition::OnIdleMonitor(unsigned mask) noexcept
{
/* send "idle" notifications to all subscribed
clients */
for (auto &client : clients)
client.IdleAdd(mask);
if (mask & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
instance.OnStateModified();
}
void
Partition::OnGlobalEvent(unsigned mask) noexcept
{

View File

@ -63,6 +63,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
boost::intrusive::constant_time_size<false>> clients;
/**
* Monitor for idle events local to this partition.
*/
MaskMonitor idle_monitor;
MaskMonitor global_events;
struct playlist playlist;
@ -91,10 +96,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
/**
* Emit an "idle" event to all clients of this partition.
*
* This method is not thread-safe and may only be called from
* the main thread.
* This method can be called from any thread.
*/
void EmitIdle(unsigned mask) noexcept;
void EmitIdle(unsigned mask) noexcept {
idle_monitor.OrMask(mask);
}
/**
* Populate the #InputCacheManager with soon-to-be-played song
@ -282,6 +288,9 @@ private:
/* virtual methods from class MixerListener */
void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override;
/* callback for #idle_monitor */
void OnIdleMonitor(unsigned mask) noexcept;
/* callback for #global_events */
void OnGlobalEvent(unsigned mask) noexcept;
};

View File

@ -34,12 +34,3 @@ ClientList::Remove(Client &client) noexcept
list.erase(list.iterator_to(client));
}
void
ClientList::IdleAdd(unsigned flags) noexcept
{
assert(flags != 0);
for (auto &client : list)
client.IdleAdd(flags);
}

View File

@ -56,8 +56,6 @@ public:
}
void Remove(Client &client) noexcept;
void IdleAdd(unsigned flags) noexcept;
};
#endif