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,24 +22,29 @@
#include "ardour/libardour_visibility.h"
#ifndef NDEBUG
# define TRACE_SETSESSION_NULL
#endif
namespace ARDOUR {
class Session;
class LIBARDOUR_API SessionHandleRef : public PBD::ScopedConnectionList
{
public:
public:
SessionHandleRef (ARDOUR::Session& s);
virtual ~SessionHandleRef ();
protected:
ARDOUR::Session& _session;
protected:
virtual void session_going_away ();
virtual void insanity_check ();
ARDOUR::Session& _session;
};
class LIBARDOUR_API SessionHandlePtr
{
public:
public:
SessionHandlePtr (ARDOUR::Session* s);
SessionHandlePtr () : _session (0) {}
virtual ~SessionHandlePtr () {}
@ -47,11 +52,16 @@ class LIBARDOUR_API SessionHandlePtr
virtual void set_session (ARDOUR::Session *);
virtual ARDOUR::Session* session() const { return _session; }
protected:
protected:
virtual void session_going_away ();
ARDOUR::Session* _session;
PBD::ScopedConnectionList _session_connections;
virtual void session_going_away ();
#ifdef TRACE_SETSESSION_NULL
private:
bool _gone_away_emitted;
#endif
};
} /* namespace */

View File

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

View File

@ -19,6 +19,11 @@
#include "pbd/demangle.h"
#include "pbd/error.h"
#ifdef TRACE_SETSESSION_NULL
#include <cassert>
#include "pbd/stacktrace.h"
#endif
#include "ardour/boost_debug.h"
#include "ardour/session.h"
#include "ardour/session_handle.h"
@ -31,6 +36,9 @@ using namespace PBD;
SessionHandlePtr::SessionHandlePtr (Session* s)
: _session (s)
#ifdef TRACE_SETSESSION_NULL
, _gone_away_emitted (false)
#endif
{
if (_session) {
_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 ();
#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) {
_session = 0;
}
@ -49,13 +83,23 @@ SessionHandlePtr::set_session (Session* s)
if (s) {
_session = s;
_session->DropReferences.connect_same_thread (_session_connections, std::bind (&SessionHandlePtr::session_going_away, this));
#ifdef TRACE_SETSESSION_NULL
_gone_away_emitted = false;
#endif
}
}
void
SessionHandlePtr::session_going_away ()
{
#ifdef TRACE_SETSESSION_NULL
if (_session && !_gone_away_emitted) {
_gone_away_emitted = true;
set_session (0);
}
#else
set_session (0);
#endif
}
/*-------------------------*/