From 01b06906b015bf1ebb972cb82cd06fb20fb2e526 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 9 Jun 2022 02:06:54 +0200 Subject: [PATCH] Mitigate "POOL OUT OF MEMORY" when batch changing controllables --- libs/ardour/session_rtevents.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc index 8ff11a7523..408d9d89df 100644 --- a/libs/ardour/session_rtevents.cc +++ b/libs/ardour/session_rtevents.cc @@ -46,6 +46,31 @@ Session::set_controls (boost::shared_ptr cl, double val, Controllab return; } +#if 1 + /* This is called by the GUI thread, so we can wait if neccessary to prevent + * "POOL OUT OF MEMORY" fatal errors. + * + * This is not a good solution, because if this happens + * event_loop->call_slot() will most likely also fail to queue a request + * to delete the Events. There is likely an additional Changed() signal + * which needds a EventLoop RequestBuffer slot. + * + * Ideally the EventLoop RequestBuffer would be at least twice the size + * of the the SessionEvent Pool, but it isn't, and even then there may + * still be other signals scheduling events... + * + */ + if (SessionEvent::pool_available () < 8) { + int sleeptm = std::max (40000, engine().usecs_per_cycle ()); + int timeout = std::max (10, 1000000 / sleeptm); + do { + usleep (sleeptm); + ARDOUR::GUIIdle (); + } + while (SessionEvent::pool_available () < 8 && --timeout > 0); + } +#endif + for (ControlList::iterator ci = cl->begin(); ci != cl->end(); ++ci) { /* as of july 2017 this is a no-op for everything except record enable */ (*ci)->pre_realtime_queue_stuff (val, gcd);