Commit 49309b41 authored by Max Kellermann's avatar Max Kellermann

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.
parent 879bafb8
...@@ -180,10 +180,7 @@ Instance::OnRemoteTag(const char *uri, const Tag &tag) noexcept ...@@ -180,10 +180,7 @@ Instance::OnRemoteTag(const char *uri, const Tag &tag) noexcept
void void
Instance::OnIdle(unsigned flags) noexcept Instance::OnIdle(unsigned flags) noexcept
{ {
/* send "idle" notifications to all subscribed /* broadcast to all partitions */
clients */ for (auto &partition : partitions)
client_list->IdleAdd(flags); partition.EmitIdle(flags);
if (flags & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
OnStateModified();
} }
...@@ -101,6 +101,10 @@ struct Instance final ...@@ -101,6 +101,10 @@ struct Instance final
std::unique_ptr<InputCacheManager> input_cache; std::unique_ptr<InputCacheManager> input_cache;
/**
* Monitor for global idle events to be broadcasted to all
* partitions.
*/
MaskMonitor idle_monitor; MaskMonitor idle_monitor;
#ifdef ENABLE_NEIGHBOR_PLUGINS #ifdef ENABLE_NEIGHBOR_PLUGINS
......
...@@ -40,6 +40,7 @@ Partition::Partition(Instance &_instance, ...@@ -40,6 +40,7 @@ Partition::Partition(Instance &_instance,
:instance(_instance), :instance(_instance),
name(_name), name(_name),
listener(new ClientListener(instance.event_loop, *this)), 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)), global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
playlist(max_length, *this), playlist(max_length, *this),
outputs(*this), outputs(*this),
...@@ -60,12 +61,6 @@ Partition::BeginShutdown() noexcept ...@@ -60,12 +61,6 @@ Partition::BeginShutdown() noexcept
listener.reset(); listener.reset();
} }
void
Partition::EmitIdle(unsigned mask) noexcept
{
instance.EmitIdle(mask);
}
static void static void
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
{ {
...@@ -216,6 +211,18 @@ Partition::OnMixerVolumeChanged(Mixer &, int) noexcept ...@@ -216,6 +211,18 @@ Partition::OnMixerVolumeChanged(Mixer &, int) noexcept
} }
void 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 Partition::OnGlobalEvent(unsigned mask) noexcept
{ {
if ((mask & SYNC_WITH_PLAYER) != 0) if ((mask & SYNC_WITH_PLAYER) != 0)
......
...@@ -63,6 +63,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener { ...@@ -63,6 +63,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
boost::intrusive::link_mode<boost::intrusive::normal_link>>>, boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
boost::intrusive::constant_time_size<false>> clients; boost::intrusive::constant_time_size<false>> clients;
/**
* Monitor for idle events local to this partition.
*/
MaskMonitor idle_monitor;
MaskMonitor global_events; MaskMonitor global_events;
struct playlist playlist; struct playlist playlist;
...@@ -91,10 +96,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener { ...@@ -91,10 +96,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
/** /**
* Emit an "idle" event to all clients of this partition. * Emit an "idle" event to all clients of this partition.
* *
* This method is not thread-safe and may only be called from * This method can be called from any thread.
* the main thread.
*/ */
void EmitIdle(unsigned mask) noexcept; void EmitIdle(unsigned mask) noexcept {
idle_monitor.OrMask(mask);
}
/** /**
* Populate the #InputCacheManager with soon-to-be-played song * Populate the #InputCacheManager with soon-to-be-played song
...@@ -282,6 +288,9 @@ private: ...@@ -282,6 +288,9 @@ private:
/* virtual methods from class MixerListener */ /* virtual methods from class MixerListener */
void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override; void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override;
/* callback for #idle_monitor */
void OnIdleMonitor(unsigned mask) noexcept;
/* callback for #global_events */ /* callback for #global_events */
void OnGlobalEvent(unsigned mask) noexcept; void OnGlobalEvent(unsigned mask) noexcept;
}; };
......
...@@ -34,12 +34,3 @@ ClientList::Remove(Client &client) noexcept ...@@ -34,12 +34,3 @@ ClientList::Remove(Client &client) noexcept
list.erase(list.iterator_to(client)); list.erase(list.iterator_to(client));
} }
void
ClientList::IdleAdd(unsigned flags) noexcept
{
assert(flags != 0);
for (auto &client : list)
client.IdleAdd(flags);
}
...@@ -56,8 +56,6 @@ public: ...@@ -56,8 +56,6 @@ public:
} }
void Remove(Client &client) noexcept; void Remove(Client &client) noexcept;
void IdleAdd(unsigned flags) noexcept;
}; };
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment