Clean up after generic MIDI surface -- #7311
authorRobin Gareus <robin@gareus.org>
Sun, 16 Apr 2017 16:55:42 +0000 (18:55 +0200)
committerRobin Gareus <robin@gareus.org>
Sun, 16 Apr 2017 17:06:17 +0000 (19:06 +0200)
When there are some non-released MIDIControllables, signal are still
delivered to the objects, even if there's no surface thread to handle
the signals anymore.

libs/surfaces/generic_midi/generic_midi_control_protocol.cc

index 7f711d7afefbc4c21ee69648d622842dbf06d32d..0e072f49b3432dac27a03a5a0f41203ee392c581 100644 (file)
@@ -224,6 +224,10 @@ GenericMidiControlProtocol::drop_all ()
        controllables.clear ();
 
        for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
+               (*i)->connection.disconnect();
+               if ((*i)->own_mc) {
+                       delete (*i)->mc;
+               }
                delete *i;
        }
        pending_controllables.clear ();
@@ -363,19 +367,17 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
        {
                Glib::Threads::Mutex::Lock lm (pending_lock);
 
-               MIDIPendingControllables::iterator ptmp;
                for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
-                       ptmp = i;
-                       ++ptmp;
                        if (((*i)->mc)->get_controllable() == c) {
+                               (*i)->connection.disconnect();
                                if ((*i)->own_mc) {
                                        delete (*i)->mc;
                                }
-                               (*i)->connection.disconnect();
                                delete *i;
-                               pending_controllables.erase (i);
+                               i = pending_controllables.erase (i);
+                       } else {
+                               ++i;
                        }
-                       i = ptmp;
                }
        }
 
@@ -414,19 +416,14 @@ GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
        Glib::Threads::Mutex::Lock lm (pending_lock);
        Glib::Threads::Mutex::Lock lm2 (controllables_lock);
 
-       MIDIPendingControllables::iterator tmp;
-
        for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
-               tmp = i;
-               ++tmp;
-
                if ( (*i)->mc == mc) {
                        (*i)->connection.disconnect();
                        delete *i;
-                       pending_controllables.erase(i);
+                       i = pending_controllables.erase(i);
+               } else {
+                       ++i;
                }
-
-               i = tmp;
        }
 
        /* add the controllable for which learning stopped to our list of
@@ -654,6 +651,10 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
        {
                Glib::Threads::Mutex::Lock lm (pending_lock);
                for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
+                       (*i)->connection.disconnect();
+                       if ((*i)->own_mc) {
+                               delete (*i)->mc;
+                       }
                        delete *i;
                }
                pending_controllables.clear ();
@@ -694,6 +695,9 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
 
                                                        if (mc->set_state (**niter, version) == 0) {
                                                                controllables.push_back (mc);
+                                                       } else {
+                                                               warning << string_compose ("Generic MIDI control: Failed to set state for Control ID: %1\n", id.to_s());
+                                                               delete mc;
                                                        }
 
                                                } else {
@@ -787,8 +791,8 @@ GenericMidiControlProtocol::load_bindings (const string& xmlpath)
                        if (child->property ("uri")) {
                                /* controllable */
 
+                               Glib::Threads::Mutex::Lock lm2 (controllables_lock);
                                if ((mc = create_binding (*child)) != 0) {
-                                       Glib::Threads::Mutex::Lock lm2 (controllables_lock);
                                        controllables.push_back (mc);
                                }