Found while fixing AUV2-1 (stale audio during a plugin-requested restart) in the 0.16 release review. Not fixed there — it is a distinct defect on the same path.
The problem
In src/wrapasauv2.cpp, onIdle()'s restart path:
activateCLAP() ignores the return value of Plugin::activate().
deactivateCLAP() calls stop_processing() and deactivate() unguarded.
So if a plugin-requested restart fails to reactivate, _initialized stays false and the wrapper carries on. A later AU Uninitialize then calls stop_processing()/deactivate() on a plugin that is already inactive — which CLAP's state machine does not allow.
The onIdle comment acknowledges the failure is possible ("If it fails anyway, _initialized stays false…"), but nothing records that the CLAP is now down as opposed to running but not initialized, and the teardown path cannot tell the two apart.
Suggested fix
Track CLAP activation state explicitly rather than inferring it from _initialized, and make deactivateCLAP() a no-op when the plugin is not active. activateCLAP() should propagate the failure so the caller can decide, rather than discarding it.
Found while fixing AUV2-1 (stale audio during a plugin-requested restart) in the 0.16 release review. Not fixed there — it is a distinct defect on the same path.
The problem
In
src/wrapasauv2.cpp,onIdle()'s restart path:activateCLAP()ignores the return value ofPlugin::activate().deactivateCLAP()callsstop_processing()anddeactivate()unguarded.So if a plugin-requested restart fails to reactivate,
_initializedstays false and the wrapper carries on. A later AUUninitializethen callsstop_processing()/deactivate()on a plugin that is already inactive — which CLAP's state machine does not allow.The
onIdlecomment acknowledges the failure is possible ("If it fails anyway,_initializedstays false…"), but nothing records that the CLAP is now down as opposed to running but not initialized, and the teardown path cannot tell the two apart.Suggested fix
Track CLAP activation state explicitly rather than inferring it from
_initialized, and makedeactivateCLAP()a no-op when the plugin is not active.activateCLAP()should propagate the failure so the caller can decide, rather than discarding it.