WebSockets: less invasive version of 5407232
There is no need to connect signals twice, can connect them directly to the helper UI loop and skip the surface loop. Then let the server decide if it is necessary to call lws_cancel_service() or not. Also rename WebsocketsServer::should_request_write() to read_blocks_event_loop() it makes more sense for the caller now on-demand write logic is completely implemented by the server class.
This commit is contained in:
parent
fc6fd7973f
commit
cb73eb350d
@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
|
||||
BasicUI& basic_ui () const;
|
||||
PBD::EventLoop* event_loop () const;
|
||||
virtual PBD::EventLoop* event_loop () const;
|
||||
Glib::RefPtr<Glib::MainLoop> main_loop () const;
|
||||
ARDOUR::Session& session () const;
|
||||
ArdourMixer& mixer () const;
|
||||
|
@ -30,20 +30,9 @@
|
||||
// TO DO: make this configurable
|
||||
#define POLL_INTERVAL_MS 100
|
||||
|
||||
#define OPTIONAL_CONNECT_HELPER(s,c) if (server ().should_request_write ()) \
|
||||
s.connect (c, MISSING_INVALIDATOR, boost::bind<void> \
|
||||
(ServerWriteObserver (), &server ()), &_helper);
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace ArdourSurface;
|
||||
|
||||
struct ServerWriteObserver {
|
||||
void operator() (WebsocketsServer *server)
|
||||
{
|
||||
server->request_write ();
|
||||
}
|
||||
};
|
||||
|
||||
struct TransportObserver {
|
||||
void operator() (ArdourFeedback* p)
|
||||
{
|
||||
@ -141,11 +130,11 @@ ArdourFeedback::start ()
|
||||
|
||||
// server must be started before feedback otherwise
|
||||
// should_request_write() will always return false
|
||||
if (!server ().should_request_write ()) {
|
||||
periodic_timeout->attach (main_loop ()->get_context ());
|
||||
} else {
|
||||
if (server ().read_blocks_event_loop ()) {
|
||||
_helper.run();
|
||||
periodic_timeout->attach (_helper.main_loop()->get_context ());
|
||||
} else {
|
||||
periodic_timeout->attach (main_loop ()->get_context ());
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -154,7 +143,7 @@ ArdourFeedback::start ()
|
||||
int
|
||||
ArdourFeedback::stop ()
|
||||
{
|
||||
if (server ().should_request_write ()) {
|
||||
if (server ().read_blocks_event_loop ()) {
|
||||
_helper.quit();
|
||||
}
|
||||
|
||||
@ -207,6 +196,16 @@ ArdourFeedback::update_all (std::string node, uint32_t strip_id, uint32_t plugin
|
||||
server ().update_all_clients (NodeState (node, addr, val), false);
|
||||
}
|
||||
|
||||
PBD::EventLoop*
|
||||
ArdourFeedback::event_loop () const
|
||||
{
|
||||
if (server ().read_blocks_event_loop ()) {
|
||||
return static_cast<PBD::EventLoop*> (&_helper);
|
||||
} else {
|
||||
return SurfaceComponent::event_loop ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ArdourFeedback::poll () const
|
||||
{
|
||||
@ -219,10 +218,6 @@ ArdourFeedback::poll () const
|
||||
update_all (Node::strip_meter, it->first, db);
|
||||
}
|
||||
|
||||
if (server ().should_request_write ()) {
|
||||
server ().request_write ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -232,15 +227,10 @@ ArdourFeedback::observe_transport ()
|
||||
ARDOUR::Session& sess = session ();
|
||||
sess.TransportStateChange.connect (_transport_connections, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (TransportObserver (), this), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(sess.TransportStateChange, _transport_connections);
|
||||
|
||||
sess.RecordStateChanged.connect (_transport_connections, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (RecordStateObserver (), this), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(sess.RecordStateChanged, _transport_connections);
|
||||
|
||||
sess.tempo_map ().PropertyChanged.connect (_transport_connections, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (TempoObserver (), this), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(sess.tempo_map ().PropertyChanged, _transport_connections);
|
||||
}
|
||||
|
||||
void
|
||||
@ -254,17 +244,14 @@ ArdourFeedback::observe_mixer ()
|
||||
|
||||
stripable->gain_control ()->Changed.connect (*it->second, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (StripGainObserver (), this, strip_id), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(stripable->gain_control ()->Changed, *it->second);
|
||||
|
||||
if (stripable->pan_azimuth_control ()) {
|
||||
stripable->pan_azimuth_control ()->Changed.connect (*it->second, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (StripPanObserver (), this, strip_id), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(stripable->pan_azimuth_control ()->Changed, *it->second);
|
||||
}
|
||||
|
||||
stripable->mute_control ()->Changed.connect (*it->second, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (StripMuteObserver (), this, strip_id), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(stripable->mute_control ()->Changed, *it->second);
|
||||
|
||||
observe_strip_plugins (strip_id, strip->plugins ());
|
||||
}
|
||||
@ -284,7 +271,6 @@ ArdourFeedback::observe_strip_plugins (uint32_t strip_id, ArdourMixerStrip::Plug
|
||||
if (control) {
|
||||
control->Changed.connect (*plugin, MISSING_INVALIDATOR,
|
||||
boost::bind<void> (PluginBypassObserver (), this, strip_id, plugin_id), event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(control->Changed, *plugin);
|
||||
}
|
||||
|
||||
for (uint32_t param_id = 0; param_id < plugin->param_count (); ++param_id) {
|
||||
@ -295,7 +281,6 @@ ArdourFeedback::observe_strip_plugins (uint32_t strip_id, ArdourMixerStrip::Plug
|
||||
boost::bind<void> (PluginParamValueObserver (), this, strip_id, plugin_id, param_id,
|
||||
boost::weak_ptr<AutomationControl>(control)),
|
||||
event_loop ());
|
||||
OPTIONAL_CONNECT_HELPER(control->Changed, *plugin);
|
||||
} catch (ArdourMixerNotFoundException& e) {
|
||||
/* ignore */
|
||||
}
|
||||
|
@ -62,8 +62,10 @@ private:
|
||||
PBD::ScopedConnectionList _transport_connections;
|
||||
sigc::connection _periodic_connection;
|
||||
|
||||
// Only needed for server event loop integration method 3
|
||||
FeedbackHelperUI _helper;
|
||||
// Only needed for server event loop integration method #3
|
||||
mutable FeedbackHelperUI _helper;
|
||||
|
||||
PBD::EventLoop* event_loop () const override;
|
||||
|
||||
bool poll () const;
|
||||
|
||||
|
@ -218,7 +218,7 @@ WebsocketsServer::update_client (Client wsi, const NodeState& state, bool force)
|
||||
/* write to client only if state was updated */
|
||||
it->second.update_state (state);
|
||||
it->second.output_buf ().push_back (NodeStateMessage (state));
|
||||
lws_callback_on_writable (wsi);
|
||||
request_write (wsi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ WebsocketsServer::write_client (Client wsi)
|
||||
}
|
||||
|
||||
if (!pending.empty ()) {
|
||||
lws_callback_on_writable (wsi);
|
||||
request_write (wsi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -360,7 +360,7 @@ WebsocketsServer::send_availsurf_hdr (Client wsi)
|
||||
}
|
||||
#endif
|
||||
|
||||
lws_callback_on_writable (wsi);
|
||||
request_write (wsi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -393,6 +393,17 @@ WebsocketsServer::send_availsurf_body (Client wsi)
|
||||
return -1; // end connection
|
||||
}
|
||||
|
||||
void
|
||||
WebsocketsServer::request_write (Client wsi)
|
||||
{
|
||||
lws_callback_on_writable (wsi);
|
||||
|
||||
if (read_blocks_event_loop ()) {
|
||||
// cancel lws_service() in the idle callback to write pending data asap
|
||||
lws_cancel_service (_lws_context);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WebsocketsServer::lws_callback (struct lws* wsi, enum lws_callback_reasons reason,
|
||||
void* user, void* in, size_t len)
|
||||
@ -631,13 +642,6 @@ WebsocketsServer::ioc_to_events (IOCondition ioc)
|
||||
return events;
|
||||
}
|
||||
|
||||
void
|
||||
WebsocketsServer::request_write ()
|
||||
{
|
||||
// cancel lws_service() in the idle callback to write pending data asap
|
||||
lws_cancel_service (_lws_context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
WebsocketsServer::glib_idle_callback (void *data)
|
||||
{
|
||||
|
@ -75,6 +75,8 @@ private:
|
||||
int send_availsurf_hdr (Client);
|
||||
int send_availsurf_body (Client);
|
||||
|
||||
void request_write (Client);
|
||||
|
||||
static int lws_callback (struct lws*, enum lws_callback_reasons, void*, void*, size_t);
|
||||
|
||||
/* Glib event loop integration that requires LWS_WITH_EXTERNAL_POLL */
|
||||
@ -115,8 +117,7 @@ private:
|
||||
static gboolean glib_idle_callback (void *);
|
||||
|
||||
public:
|
||||
bool should_request_write () { return _g_source != 0; }
|
||||
void request_write ();
|
||||
bool read_blocks_event_loop () { return _g_source != 0; }
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user