13
0

Debug set_session(0) calls preventing session_going_away()

This commit is contained in:
Robin Gareus 2024-11-06 03:41:17 +01:00
parent 983236f348
commit 0f0006cebc
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 65 additions and 6 deletions

View File

@ -22,6 +22,10 @@
#include "ardour/libardour_visibility.h" #include "ardour/libardour_visibility.h"
#ifndef NDEBUG
# define TRACE_SETSESSION_NULL
#endif
namespace ARDOUR { namespace ARDOUR {
class Session; class Session;
@ -32,9 +36,10 @@ class LIBARDOUR_API SessionHandleRef : public PBD::ScopedConnectionList
virtual ~SessionHandleRef (); virtual ~SessionHandleRef ();
protected: protected:
ARDOUR::Session& _session;
virtual void session_going_away (); virtual void session_going_away ();
virtual void insanity_check (); virtual void insanity_check ();
ARDOUR::Session& _session;
}; };
class LIBARDOUR_API SessionHandlePtr class LIBARDOUR_API SessionHandlePtr
@ -48,10 +53,15 @@ class LIBARDOUR_API SessionHandlePtr
virtual ARDOUR::Session* session() const { return _session; } virtual ARDOUR::Session* session() const { return _session; }
protected: protected:
virtual void session_going_away ();
ARDOUR::Session* _session; ARDOUR::Session* _session;
PBD::ScopedConnectionList _session_connections; PBD::ScopedConnectionList _session_connections;
virtual void session_going_away (); #ifdef TRACE_SETSESSION_NULL
private:
bool _gone_away_emitted;
#endif
}; };
} /* namespace */ } /* namespace */

View File

@ -463,7 +463,12 @@ AudioEngine::process_callback (pframes_t nframes)
/* fade out done */ /* fade out done */
PortManager::silence_outputs (nframes); PortManager::silence_outputs (nframes);
session_deleted = true; session_deleted = true;
#ifdef TRACE_SETSESSION_NULL
_session_connections.drop_connections ();
_session = 0;
#else
SessionHandlePtr::set_session (0); SessionHandlePtr::set_session (0);
#endif
session_removal_countdown = -1; // reset to "not in progress" session_removal_countdown = -1; // reset to "not in progress"
session_remove_pending = false; session_remove_pending = false;
session_removed.signal(); // wakes up thread that initiated session removal session_removed.signal(); // wakes up thread that initiated session removal

View File

@ -19,6 +19,11 @@
#include "pbd/demangle.h" #include "pbd/demangle.h"
#include "pbd/error.h" #include "pbd/error.h"
#ifdef TRACE_SETSESSION_NULL
#include <cassert>
#include "pbd/stacktrace.h"
#endif
#include "ardour/boost_debug.h" #include "ardour/boost_debug.h"
#include "ardour/session.h" #include "ardour/session.h"
#include "ardour/session_handle.h" #include "ardour/session_handle.h"
@ -31,6 +36,9 @@ using namespace PBD;
SessionHandlePtr::SessionHandlePtr (Session* s) SessionHandlePtr::SessionHandlePtr (Session* s)
: _session (s) : _session (s)
#ifdef TRACE_SETSESSION_NULL
, _gone_away_emitted (false)
#endif
{ {
if (_session) { if (_session) {
_session->DropReferences.connect_same_thread (_session_connections, std::bind (&SessionHandlePtr::session_going_away, this)); _session->DropReferences.connect_same_thread (_session_connections, std::bind (&SessionHandlePtr::session_going_away, this));
@ -42,6 +50,32 @@ SessionHandlePtr::set_session (Session* s)
{ {
_session_connections.drop_connections (); _session_connections.drop_connections ();
#ifdef TRACE_SETSESSION_NULL
/* DropReferences may already have been disconnected due to signal emission ordering.
*
* An instance of this class (e.g. Ardour_UI) will need to call ::set_session() on member instances.
*
* Yet, when session_going_away() first calls set_session (0) on an instance that has SessionHandlePtr members,
* they will reach here, and disocnnect signal handlers. Their derived implementation of ::session_going_away()
* will not be called.
*/
if (!_gone_away_emitted && _session && !s) {
/* if this assert goes off, some ::set_session() implementation calls
* some_member->set_session (0);
*
* replace it with
*
* if (session) {
* some_member->set_session (session);
* }
*/
PBD::stacktrace (cerr, 10);
assert (0);
_gone_away_emitted = true;
session_going_away ();
}
#endif
if (_session) { if (_session) {
_session = 0; _session = 0;
} }
@ -49,14 +83,24 @@ SessionHandlePtr::set_session (Session* s)
if (s) { if (s) {
_session = s; _session = s;
_session->DropReferences.connect_same_thread (_session_connections, std::bind (&SessionHandlePtr::session_going_away, this)); _session->DropReferences.connect_same_thread (_session_connections, std::bind (&SessionHandlePtr::session_going_away, this));
#ifdef TRACE_SETSESSION_NULL
_gone_away_emitted = false;
#endif
} }
} }
void void
SessionHandlePtr::session_going_away () SessionHandlePtr::session_going_away ()
{ {
#ifdef TRACE_SETSESSION_NULL
if (_session && !_gone_away_emitted) {
_gone_away_emitted = true;
set_session (0); set_session (0);
} }
#else
set_session (0);
#endif
}
/*-------------------------*/ /*-------------------------*/