Fix deletion of VCA with slaved controls.
authorRobin Gareus <robin@gareus.org>
Fri, 9 Jun 2017 20:54:09 +0000 (22:54 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 9 Jun 2017 21:25:42 +0000 (23:25 +0200)
commita1b4f9b8abf2887b17bce05403ea7eab2421f26a
treea104cbcde53d6efa1959ac451a43088292ee85d4
parent8502aa18c5e69cee79780d370ab6fa88cf7de484
Fix deletion of VCA with slaved controls.

The crashed previously because:
 A VCA is-a Automatable is-a Evoral::ControlSet

 After VCA's d'tor completes ~Automatable runs and emits signal to
 DropReferences of all master-controls.

 This in turn calls SlavableAutomationControl::master_going_away()
 for slaved parameters for the given master-control

 In ::master_going_away() the weak-pointer reference to the master's
 AutomationControl (owned by the destroyed VCA) is still valid.

 Execution is in the d'tor of Automatable which is-a ControlSet and
 the ContolSet keeps a reference to the Control and hence also to the
 AutomationControl which is-a Evoral::Control.

 So master_going_away() locks a boost::shared_ptr<ARDOUR::AutomationControl>
 which is actually the MuteControl owned by the VCA.
 It calls SlavableAutomationControl::remove_master() which
 in turn calls MuteControl::pre_remove_master() which uses the
 MuteMaster API to retrieve the value. The MuteMaster however is the
 VCA that has just been destroyed.

The solution is twofold:
 1) emit "drop_references" from the VCA d'tor itself,
    before the VCA is destroyed.

 2) disconnect a slaved control from the master's drop_references signal
    when un-assigning a master-control.
libs/ardour/ardour/automation_control.h
libs/ardour/ardour/slavable_automation_control.h
libs/ardour/slavable_automation_control.cc
libs/ardour/vca.cc