LV2/midnam tweaks - fix race conditions
authorRobin Gareus <robin@gareus.org>
Sat, 9 Sep 2017 01:07:01 +0000 (03:07 +0200)
committerRobin Gareus <robin@gareus.org>
Sat, 9 Sep 2017 01:08:46 +0000 (03:08 +0200)
* Emit signal once midnam was actually updated
* only re-read midnam if was it changed. This allows idempotent calls to
  read_midnam() - from the same thread.

At session-load a synth-plugin may load a soundfont in the background
and emit midnam_update() after the synth was initialized but before the
GUI thread connects to the signal. By making the call idempotent the
GUI can call read_midnam() after connecting to the signal to catch up.

libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/plugin.h
libs/ardour/lv2_plugin.cc

index d4b6ca819fa1adb0a96ce5872b4949e195e17520..c3d437b6f741f9585e6031dce6773dbf16305bef 100644 (file)
@@ -344,6 +344,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
        bool has_midnam ();
        bool read_midnam ();
        std::string midnam_model ();
        bool has_midnam ();
        bool read_midnam ();
        std::string midnam_model ();
+       bool _midnam_dirty;
 #endif
 
        void latency_compute_run ();
 #endif
 
        void latency_compute_run ();
index 52fbc71c68e75e6c14d3ea1165a854b2d1b83d2e..f51f34b099f1206efa7f90b1c3824e6e94359f2d 100644 (file)
@@ -182,6 +182,7 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
        virtual bool read_midnam () { return false; }
        virtual std::string midnam_model () { return ""; }
        PBD::Signal0<void> UpdateMidnam;
        virtual bool read_midnam () { return false; }
        virtual std::string midnam_model () { return ""; }
        PBD::Signal0<void> UpdateMidnam;
+       PBD::Signal0<void> UpdatedMidnam;
 
        virtual bool knows_bank_patch () { return false; }
        virtual uint32_t bank_patch (uint8_t chn) { return UINT32_MAX; }
 
        virtual bool knows_bank_patch () { return false; }
        virtual uint32_t bank_patch (uint8_t chn) { return UINT32_MAX; }
index 5311136afcd6c25142eb312fec89ec65e0124d44..b51db6548526efd1184ae173a602342d731c6c92 100644 (file)
@@ -241,6 +241,7 @@ void
 LV2Plugin::midnam_update (LV2_Midnam_Handle handle)
 {
        LV2Plugin* plugin = (LV2Plugin*)handle;
 LV2Plugin::midnam_update (LV2_Midnam_Handle handle)
 {
        LV2Plugin* plugin = (LV2Plugin*)handle;
+       plugin->_midnam_dirty = true;
        plugin->UpdateMidnam (); /* EMIT SIGNAL */
 }
 
        plugin->UpdateMidnam (); /* EMIT SIGNAL */
 }
 
@@ -590,6 +591,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
        _midname_interface = (const LV2_Midnam_Interface*)
                extension_data (LV2_MIDNAM__interface);
        if (_midname_interface) {
        _midname_interface = (const LV2_Midnam_Interface*)
                extension_data (LV2_MIDNAM__interface);
        if (_midname_interface) {
+               _midnam_dirty = true;
                read_midnam ();
        }
 #endif
                read_midnam ();
        }
 #endif
@@ -1029,7 +1031,7 @@ LV2Plugin::has_midnam () {
 bool
 LV2Plugin::read_midnam () {
        bool rv = false;
 bool
 LV2Plugin::read_midnam () {
        bool rv = false;
-       if (!_midname_interface) {
+       if (!_midname_interface || !_midnam_dirty) {
                return rv;
        }
        char* midnam = _midname_interface->midnam ((void*)_impl->instance->lv2_handle);
                return rv;
        }
        char* midnam = _midname_interface->midnam ((void*)_impl->instance->lv2_handle);
@@ -1047,6 +1049,10 @@ LV2Plugin::read_midnam () {
        }
 #endif
        _midname_interface->free (midnam);
        }
 #endif
        _midname_interface->free (midnam);
+       if (rv) {
+               UpdatedMidnam ();
+               _midnam_dirty = false;
+       }
        return rv;
 }
 
        return rv;
 }