summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-12-22 20:21:43 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-12-22 20:21:43 +0000
commitc83389b8ec5fef9553a401e6123b7e55702af9e2 (patch)
tree5580dd13b6275eefe67b9147ce96fa10db4d8674 /libs
parent87fb46859c5950af7c00111afa81a00a1fad2196 (diff)
cleanup up cleanup at session destruction; clarify the meaning of 3 signals (DropReferences & Destroyed in libardour ; CatchDeletion in the GTK UI); clarify ownership of objects (session no longer pays attention to DropReferences for objects that it is considered to own, such as routes, sources, etc); fix up MIDI parsing and a couple of other places by correcting syntax for return of values from a boost::signals2::signal (possible danger elsewhere to be checked)
git-svn-id: svn://localhost/ardour2/branches/3.0@6389 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/session.h10
-rw-r--r--libs/ardour/ardour/session_handle.h1
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/audio_playlist.cc4
-rw-r--r--libs/ardour/automation_list.cc1
-rw-r--r--libs/ardour/coreaudiosource.cc1
-rw-r--r--libs/ardour/diskstream.cc4
-rw-r--r--libs/ardour/internal_send.cc2
-rw-r--r--libs/ardour/ladspa_plugin.cc2
-rw-r--r--libs/ardour/lv2_plugin.cc2
-rw-r--r--libs/ardour/midi_diskstream.cc2
-rw-r--r--libs/ardour/midi_playlist.cc3
-rw-r--r--libs/ardour/midi_ui.cc2
-rw-r--r--libs/ardour/named_selection.cc5
-rw-r--r--libs/ardour/plugin_insert.cc1
-rw-r--r--libs/ardour/port_insert.cc1
-rw-r--r--libs/ardour/region.cc14
-rw-r--r--libs/ardour/return.cc1
-rw-r--r--libs/ardour/route.cc1
-rw-r--r--libs/ardour/route_group.cc2
-rw-r--r--libs/ardour/send.cc1
-rw-r--r--libs/ardour/session.cc78
-rw-r--r--libs/ardour/session_handle.cc16
-rw-r--r--libs/ardour/session_playlists.cc3
-rw-r--r--libs/ardour/session_state.cc5
-rw-r--r--libs/ardour/sndfilesource.cc2
-rw-r--r--libs/ardour/vst_plugin.cc1
-rw-r--r--libs/gtkmm2ext/gtk_ui.cc6
-rw-r--r--libs/midi++2/parser.cc11
-rw-r--r--libs/pbd/controllable.cc10
-rw-r--r--libs/pbd/pbd/abstract_ui.cc26
-rw-r--r--libs/pbd/pbd/abstract_ui.h8
-rw-r--r--libs/pbd/pbd/controllable.h2
-rw-r--r--libs/pbd/pbd/destructible.h11
-rw-r--r--libs/pbd/pbd/memento_command.h2
-rw-r--r--libs/pbd/pbd/pthread_utils.h7
-rw-r--r--libs/pbd/pbd/signals.h50
-rw-r--r--libs/pbd/pthread_utils.cc14
-rw-r--r--libs/pbd/undo.cc4
-rw-r--r--libs/surfaces/osc/osc.cc2
40 files changed, 176 insertions, 144 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 59a282fe1d..ae9c1f58a5 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -570,11 +570,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* named selections */
- NamedSelection* named_selection_by_name (std::string name);
- void add_named_selection (NamedSelection *);
- void remove_named_selection (NamedSelection *);
+ boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name);
+ void add_named_selection (boost::shared_ptr<NamedSelection>);
+ void remove_named_selection (boost::shared_ptr<NamedSelection>);
- template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&));
+ template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>));
PBD::Signal0<void> NamedSelectionAdded;
PBD::Signal0<void> NamedSelectionRemoved;
@@ -1287,7 +1287,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* NAMED SELECTIONS */
mutable Glib::Mutex named_selection_lock;
- typedef std::set<NamedSelection *> NamedSelectionList;
+ typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList;
NamedSelectionList named_selections;
int load_named_selections (const XMLNode&);
diff --git a/libs/ardour/ardour/session_handle.h b/libs/ardour/ardour/session_handle.h
index 87c6fb6670..87de244e42 100644
--- a/libs/ardour/ardour/session_handle.h
+++ b/libs/ardour/ardour/session_handle.h
@@ -34,6 +34,7 @@ class SessionHandleRef : public PBD::ScopedConnectionList
protected:
ARDOUR::Session& _session;
virtual void session_going_away ();
+ virtual void insanity_check ();
};
class SessionHandlePtr
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index f8dc553ae0..fb225671e9 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1505,7 +1505,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
continue; /* XXX is this OK? */
}
- region->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region)));
+ region->DropReferences.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region)));
_last_capture_regions.push_back (region);
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 3379868d60..1ecba28653 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -102,10 +102,6 @@ AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nfra
AudioPlaylist::~AudioPlaylist ()
{
- drop_references ();
-
- /* drop connections to signals */
-
_crossfades.clear ();
}
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index 3543f8b51f..3ecf3f0172 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -112,7 +112,6 @@ AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id)
AutomationList::~AutomationList()
{
- drop_references ();
}
boost::shared_ptr<Evoral::ControlList>
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index bbb0d8ca89..1b3a77bc39 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -90,7 +90,6 @@ CoreAudioSource::init_cafile ()
CoreAudioSource::~CoreAudioSource ()
{
- drop_references ();
}
int
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index a37323de84..7004ef1ed5 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -148,7 +148,7 @@ Diskstream::set_route (Route& r)
non_realtime_input_change ();
set_align_style_from_io ();
- _route->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this));
+ _route->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this));
}
void
@@ -340,7 +340,7 @@ Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
}
_playlist->Modified.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this));
- _playlist->GoingAway.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist)));
+ _playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist)));
_playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_ranges_moved, this, _1));
}
diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc
index 368eff2be4..4a4823a29f 100644
--- a/libs/ardour/internal_send.cc
+++ b/libs/ardour/internal_send.cc
@@ -43,7 +43,7 @@ InternalSend::InternalSend (Session& s, boost::shared_ptr<MuteMaster> mm, boost:
set_name (sendto->name());
- _send_to->GoingAway.connect_same_thread (*this, boost::bind (&InternalSend::send_to_going_away, this));
+ _send_to->DropReferences.connect_same_thread (*this, boost::bind (&InternalSend::send_to_going_away, this));
_send_to->NameChanged.connect_same_thread (*this, boost::bind (&InternalSend::send_to_name_changed, this));
}
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index bbd29e960e..7abcca2718 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -144,8 +144,6 @@ LadspaPlugin::~LadspaPlugin ()
deactivate ();
cleanup ();
- drop_references ();
-
/* XXX who should close a plugin? */
// dlclose (module);
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 6c593a869a..39bd8d75a7 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -181,8 +181,6 @@ LV2Plugin::~LV2Plugin ()
deactivate ();
cleanup ();
- drop_references ();
-
slv2_instance_free(_instance);
slv2_value_free(_name);
slv2_value_free(_author);
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 17c1404358..18d3bc5ce3 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -1024,7 +1024,7 @@ MidiDiskstream::transport_stopped (struct tm& /*when*/, time_t /*twhen*/, bool a
continue; /* XXX is this OK? */
}
- region->GoingAway.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region)));
+ region->DropReferences.connect_same_thread (*this, boost::bind (&Diskstream::remove_region_from_last_capture, this, boost::weak_ptr<Region>(region)));
_last_capture_regions.push_back (region);
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index a8e60ec866..789c91b236 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -71,9 +71,6 @@ MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes
MidiPlaylist::~MidiPlaylist ()
{
- drop_references ();
-
- /* drop connections to signals */
}
template<typename Time>
diff --git a/libs/ardour/midi_ui.cc b/libs/ardour/midi_ui.cc
index 70be1f345d..aa81ff2068 100644
--- a/libs/ardour/midi_ui.cc
+++ b/libs/ardour/midi_ui.cc
@@ -89,6 +89,8 @@ MidiControlUI::change_midi_ports ()
bool
MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port)
{
+ DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", port->name()));
+
if (ioc & ~IO_IN) {
return false;
}
diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc
index a829c44a50..4bcc3f3b72 100644
--- a/libs/ardour/named_selection.cc
+++ b/libs/ardour/named_selection.cc
@@ -52,8 +52,6 @@ NamedSelection::NamedSelection (string n, PlaylistList& l)
(*i)->set_name (new_name);
(*i)->use();
}
-
- NamedSelectionCreated (this);
}
NamedSelection::NamedSelection (Session& session, const XMLNode& node)
@@ -101,8 +99,9 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
NamedSelection::~NamedSelection ()
{
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
- (*i)->release ();
+ /* XXX who really owns these? us or the session? */
(*i)->drop_references ();
+ (*i)->release ();
}
}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index c2bf7f3562..a85cc1ee86 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -130,7 +130,6 @@ PluginInsert::set_count (uint32_t num)
PluginInsert::~PluginInsert ()
{
- drop_references ();
}
void
diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc
index 044230e1f7..dee661db41 100644
--- a/libs/ardour/port_insert.cc
+++ b/libs/ardour/port_insert.cc
@@ -61,7 +61,6 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLN
PortInsert::~PortInsert ()
{
- drop_references ();
}
void
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index d706421c39..57d887f6a6 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -109,7 +109,7 @@ Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length
_sources.push_back (src);
_master_sources.push_back (src);
- src->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(src)));
+ src->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(src)));
assert(_sources.size() > 0);
_positional_lock_style = AudioTime;
@@ -338,7 +338,6 @@ Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
Region::~Region ()
{
DEBUG_TRACE (DEBUG::Destruction, string_compose ("Region %1 destructor @ %2\n", _name, this));
- drop_references ();
}
void
@@ -1416,7 +1415,12 @@ void
Region::source_deleted (boost::weak_ptr<Source>)
{
_sources.clear ();
- cerr << "Send drop ref signal from region " << ' ' << this << endl;
+
+ /* this is a very special case: at least one of the region's
+ sources has bee deleted, so invalidate all references to
+ ourselves.
+ */
+
drop_references ();
}
@@ -1586,14 +1590,14 @@ Region::use_sources (SourceList const & s)
for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) {
_sources.push_back (*i);
- (*i)->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
+ (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
unique_srcs.insert (*i);
}
for (SourceList::const_iterator i = s.begin (); i != s.end(); ++i) {
_master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
+ (*i)->DropReferences.connect_same_thread (*this, boost::bind (&Region::source_deleted, this, boost::weak_ptr<Source>(*i)));
}
}
}
diff --git a/libs/ardour/return.cc b/libs/ardour/return.cc
index 991c6ae7d1..c2c227769d 100644
--- a/libs/ardour/return.cc
+++ b/libs/ardour/return.cc
@@ -67,7 +67,6 @@ Return::Return (Session& s, const XMLNode& node, bool internal)
Return::~Return ()
{
- drop_references ();
}
XMLNode&
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index c652023e2c..09e38eaa86 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -792,6 +792,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
// XXX: do we want to emit the signal here ? change call order.
processor->activate ();
}
+
processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false));
_output->set_user_latency (0);
diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc
index 2f946dd620..d59ec82236 100644
--- a/libs/ardour/route_group.cc
+++ b/libs/ardour/route_group.cc
@@ -76,7 +76,7 @@ RouteGroup::add (boost::shared_ptr<Route> r)
routes->push_back (r);
r->join_route_group (this);
- r->GoingAway.connect_same_thread (*this, boost::bind (&RouteGroup::remove_when_going_away, this, boost::weak_ptr<Route> (r)));
+ r->DropReferences.connect_same_thread (*this, boost::bind (&RouteGroup::remove_when_going_away, this, boost::weak_ptr<Route> (r)));
_session.set_dirty ();
changed (); /* EMIT SIGNAL */
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 1bb03642d0..e4fbf3efba 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -64,7 +64,6 @@ Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, i
Send::~Send ()
{
- drop_references ();
}
void
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index a062efee8d..2e48ed0215 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -388,32 +388,19 @@ Session::destroy ()
AudioDiskstream::free_working_buffers();
- DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
- for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
- NamedSelectionList::iterator tmp;
+ /* tell everyone who is still standing that we're about to die */
+ drop_references ();
- tmp = i;
- ++tmp;
+ /* tell everyone to drop references and delete objects as we go */
- delete *i;
- i = tmp;
- }
+ DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n");
+ named_selections.clear ();
DEBUG_TRACE (DEBUG::Destruction, "delete regions\n");
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
- RegionList::iterator tmp;
-
- tmp = i;
- ++tmp;
-
- boost::shared_ptr<Region> keep (i->second);
-
- DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %3\n", i->second->name(), i->second.get(), i->second.use_count()));
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count()));
i->second->drop_references ();
- DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count()));
- i = tmp;
}
-
regions.clear ();
DEBUG_TRACE (DEBUG::Destruction, "delete routes\n");
@@ -427,10 +414,12 @@ Session::destroy ()
{
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy ();
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references ();
}
+
r->clear ();
/* writer goes out of scope and updates master */
}
@@ -444,28 +433,22 @@ Session::destroy ()
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
(*i)->drop_references ();
}
+
dsl->clear ();
}
diskstreams.flush ();
DEBUG_TRACE (DEBUG::Destruction, "delete sources\n");
- for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
- SourceMap::iterator tmp;
-
- tmp = i;
- ++tmp;
-
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count()));
i->second->drop_references ();
-
- i = tmp;
}
sources.clear ();
-
DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n");
for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
+
delete *i;
}
@@ -476,10 +459,6 @@ Session::destroy ()
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
playlists.reset ();
- /* tell everyone who is still standing that we're about to die */
-
- drop_references ();
-
boost_debug_list_ptrs ();
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
@@ -2813,8 +2792,6 @@ Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
}
region->StateChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr<Region>(region)));
- region->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_region, this, boost::weak_ptr<Region>(region)));
-
update_region_name_map (region);
}
@@ -3001,7 +2978,6 @@ Session::add_source (boost::shared_ptr<Source> source)
}
if (result.second) {
- source->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_source, this, boost::weak_ptr<Source> (source)));
set_dirty();
}
@@ -3390,10 +3366,7 @@ Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
return;
}
- bool existing = playlists->add (playlist);
- if (!existing) {
- playlist->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_playlist, this, boost::weak_ptr<Playlist>(playlist)));
- }
+ playlists->add (playlist);
if (unused) {
playlist->release();
@@ -3566,7 +3539,11 @@ Session::graph_reordered ()
void
Session::add_processor (Processor* processor)
{
- processor->GoingAway.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
+ /* Session does not own Processors (they belong to a Route) but we do want to track
+ the arrival and departure of port inserts, sends and returns for naming
+ purposes.
+ */
+ processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
set_dirty();
}
@@ -3810,37 +3787,33 @@ Session::mark_insert_id (uint32_t id)
/* Named Selection management */
-NamedSelection *
+boost::shared_ptr<NamedSelection>
Session::named_selection_by_name (string name)
{
Glib::Mutex::Lock lm (named_selection_lock);
for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
if ((*i)->name == name) {
- return* i;
+ return *i;
}
}
- return 0;
+ return boost::shared_ptr<NamedSelection>();
}
void
-Session::add_named_selection (NamedSelection* named_selection)
+Session::add_named_selection (boost::shared_ptr<NamedSelection> named_selection)
{
{
Glib::Mutex::Lock lm (named_selection_lock);
named_selections.insert (named_selections.begin(), named_selection);
}
- for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
- add_playlist (*i);
- }
-
set_dirty();
NamedSelectionAdded (); /* EMIT SIGNAL */
}
void
-Session::remove_named_selection (NamedSelection* named_selection)
+Session::remove_named_selection (boost::shared_ptr<NamedSelection> named_selection)
{
bool removed = false;
@@ -3850,7 +3823,6 @@ Session::remove_named_selection (NamedSelection* named_selection)
NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
if (i != named_selections.end()) {
- delete (*i);
named_selections.erase (i);
set_dirty();
removed = true;
@@ -4186,6 +4158,10 @@ Session::compute_initial_length ()
void
Session::sync_order_keys (std::string const & base)
{
+ if (deletion_in_progress()) {
+ return;
+ }
+
if (!Config->get_sync_all_route_ordering()) {
/* leave order keys as they are */
return;
diff --git a/libs/ardour/session_handle.cc b/libs/ardour/session_handle.cc
index 1cd78c8aac..36515505ac 100644
--- a/libs/ardour/session_handle.cc
+++ b/libs/ardour/session_handle.cc
@@ -32,7 +32,7 @@ SessionHandlePtr::SessionHandlePtr (Session* s)
: _session (s)
{
if (_session) {
- _session->GoingAway.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this));
+ _session->DropReferences.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this));
}
}
@@ -47,7 +47,7 @@ SessionHandlePtr::set_session (Session* s)
if (s) {
_session = s;
- _session->GoingAway.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this));
+ _session->DropReferences.connect_same_thread (_session_connections, boost::bind (&SessionHandlePtr::session_going_away, this));
}
}
@@ -63,11 +63,19 @@ SessionHandlePtr::session_going_away ()
SessionHandleRef::SessionHandleRef (Session& s)
: _session (s)
{
- _session.GoingAway.connect_same_thread (*this, boost::bind (&SessionHandleRef::session_going_away, this));
+ _session.DropReferences.connect_same_thread (*this, boost::bind (&SessionHandleRef::session_going_away, this));
+ _session.Destroyed.connect_same_thread (*this, boost::bind (&SessionHandleRef::insanity_check, this));
}
void
SessionHandleRef::session_going_away ()
{
- error << string_compose (_("programming error: %1"), "SessionHandleRef exists across sesssion deletion!") << endmsg;
+ /* a handleRef is allowed to exist at the time of DropReferences, but not at the time of Destroyed
+ */
+}
+
+void
+SessionHandleRef::insanity_check ()
+{
+ cerr << string_compose (_("programming error: %1"), "SessionHandleRef exists across sesssion deletion!") << endl;
}
diff --git a/libs/ardour/session_playlists.cc b/libs/ardour/session_playlists.cc
index 238bd72404..17ed6a4e30 100644
--- a/libs/ardour/session_playlists.cc
+++ b/libs/ardour/session_playlists.cc
@@ -43,6 +43,7 @@ SessionPlaylists::~SessionPlaylists ()
++tmp;
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for used playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
+ boost::shared_ptr<Playlist> keeper (*i);
(*i)->drop_references ();
i = tmp;
@@ -56,6 +57,7 @@ SessionPlaylists::~SessionPlaylists ()
++tmp;
DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for unused playlist %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count()));
+ boost::shared_ptr<Playlist> keeper (*i);
(*i)->drop_references ();
i = tmp;
@@ -291,6 +293,7 @@ SessionPlaylists::maybe_delete_unused (boost::function<int(boost::shared_ptr<Pla
/* now delete any that were marked for deletion */
for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
+ boost::shared_ptr<Playlist> keeper (*x);
(*x)->drop_references ();
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 2248663478..1742feaab1 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -274,7 +274,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
- NamedSelection::NamedSelectionCreated.connect_same_thread (*this, boost::bind (&Session::add_named_selection, this, _1));
AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
@@ -789,7 +788,7 @@ Session::load_state (string snapshot_name)
/* there is pending state from a crashed capture attempt */
- if (AskAboutPendingState()) {
+ if (*AskAboutPendingState()) {
state_was_pending = true;
}
}
@@ -1126,7 +1125,7 @@ Session::set_state (const XMLNode& node, int version)
_nominal_frame_rate = atoi (prop->value());
if (_nominal_frame_rate != _current_frame_rate) {
- if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
+ if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
return -1;
}
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 185cb15e79..d9d428a4cb 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -246,8 +246,6 @@ SndFileSource::open ()
SndFileSource::~SndFileSource ()
{
- drop_references ();
-
if (sf) {
sf_close (sf);
sf = 0;
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index ee3ebd2ee3..80631ac840 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -102,7 +102,6 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
VSTPlugin::~VSTPlugin ()
{
deactivate ();
- drop_references ();
fst_close (_fst);
}
diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc
index 38512d70f5..318dedd1fc 100644
--- a/libs/gtkmm2ext/gtk_ui.cc
+++ b/libs/gtkmm2ext/gtk_ui.cc
@@ -359,7 +359,11 @@ UI::do_request (UIRequest* req)
do_quit ();
} else if (req->type == CallSlot) {
-
+#ifndef NDEBUG
+ if (getenv ("DEBUG_THREADED_SIGNALS")) {
+ cerr << "call slot for " << name() << endl;
+ }
+#endif
req->the_slot ();
} else if (req->type == TouchDisplay) {
diff --git a/libs/midi++2/parser.cc b/libs/midi++2/parser.cc
index af9cfafaca..60a321cefb 100644
--- a/libs/midi++2/parser.cc
+++ b/libs/midi++2/parser.cc
@@ -313,7 +313,6 @@ Parser::trace (bool onoff, ostream *o, const string &prefix)
trace_connection.disconnect ();
if (onoff) {
- cerr << "enabling tracing for port " << _port.name() << endl;
trace_stream = o;
trace_prefix = prefix;
any.connect_same_thread (trace_connection, boost::bind (&Parser::trace_event, this, _1, _2, _3));
@@ -402,8 +401,9 @@ Parser::scanner (unsigned char inbyte)
* an EOX. Actually, since EOX is a status byte, this
* code ALWAYS handles the end of a VARIABLELENGTH message.
*/
-
+
if (state == VARIABLELENGTH && statusbit) {
+
/* The message has ended, so process it */
/* add EOX to any sysex message */
@@ -419,7 +419,7 @@ Parser::scanner (unsigned char inbyte)
}
cerr << dec << endl;
#endif
- if (msgindex > 0 && edit (msgbuf, msgindex) >= 0) {
+ if (msgindex > 0 && (edit.empty() || !(*edit (msgbuf, msgindex) >= 0))) {
if (!possible_mmc (msgbuf, msgindex) || _mmc_forward) {
if (!possible_mtc (msgbuf, msgindex) || _mtc_forward) {
if (!_offline) {
@@ -429,7 +429,7 @@ Parser::scanner (unsigned char inbyte)
}
if (!_offline) {
any (*this, msgbuf, msgindex);
- }
+ }
}
}
@@ -490,8 +490,7 @@ Parser::scanner (unsigned char inbyte)
case NEEDONEBYTE:
/* We've completed a 1 or 2 byte message. */
-
- if (edit (msgbuf, msgindex) == 0) {
+ if (edit.empty() || !(*edit (msgbuf, msgindex) == 0)) {
/* message not cancelled by an editor */
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
index d751c3c80b..be487a0a87 100644
--- a/libs/pbd/controllable.cc
+++ b/libs/pbd/controllable.cc
@@ -62,23 +62,23 @@ Controllable::add (Controllable& ctl)
/* Controllable::remove() is static - no need to manage this connection */
- ctl.GoingAway.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, ref (ctl)));
+ ctl.DropReferences.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, &ctl));
}
void
-Controllable::remove (Controllable& ctl)
+Controllable::remove (Controllable* ctl)
{
Glib::RWLock::WriterLock lm (registry_lock);
for (Controllables::iterator i = registry.begin(); i != registry.end(); ++i) {
- if ((*i) == &ctl) {
+ if ((*i) == ctl) {
registry.erase (i);
break;
}
}
- if (!ctl.uri().empty()) {
- ControllablesByURI::iterator i = registry_by_uri.find (ctl.uri());
+ if (!ctl->uri().empty()) {
+ ControllablesByURI::iterator i = registry_by_uri.find (ctl->uri());
if (i != registry_by_uri.end()) {
registry_by_uri.erase (i);
}
diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc
index 98ef094a00..cc7010a415 100644
--- a/libs/pbd/pbd/abstract_ui.cc
+++ b/libs/pbd/pbd/abstract_ui.cc
@@ -1,4 +1,5 @@
#include <unistd.h>
+#include <iostream>
#include "pbd/stacktrace.h"
#include "pbd/abstract_ui.h"
@@ -9,11 +10,22 @@
using namespace std;
+static void do_not_delete_the_request_buffer (void*) { }
+
+template<typename R>
+Glib::StaticPrivate<typename AbstractUI<R>::RequestBuffer> AbstractUI<R>::per_thread_request_buffer;
+
template <typename RequestObject>
AbstractUI<RequestObject>::AbstractUI (const string& name)
: BaseUI (name)
{
- PBD::ThreadCreatedWithRequestSize.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread));
+ void (AbstractUI<RequestObject>::*pmf)(string,pthread_t,string,uint32_t) = &AbstractUI<RequestObject>::register_thread;
+
+ /* better to make this connect a handler that runs in the UI event loop but the syntax seems hard, and
+ register_thread() is thread safe anyway.
+ */
+
+ PBD::ThreadCreatedWithRequestSize.connect_same_thread (new_thread_connection, boost::bind (pmf, this, _1, _2, _3, _4));
}
template <typename RequestObject> void
@@ -30,7 +42,7 @@ AbstractUI<RequestObject>::register_thread (string target_gui, pthread_t thread_
request_buffers[thread_id] = b;
}
- per_thread_request_buffer.set (b);
+ per_thread_request_buffer.set (b, do_not_delete_the_request_buffer);
}
template <typename RequestObject> RequestObject*
@@ -143,6 +155,11 @@ template<typename RequestObject> void
AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f)
{
if (caller_is_self()) {
+#ifndef NDEBUG
+ if (getenv ("DEBUG_THREADED_SIGNALS")) {
+ std::cerr << "functor called in correct thread for " << name() << " , execute ...\n";
+ }
+#endif
f ();
return;
}
@@ -154,6 +171,11 @@ AbstractUI<RequestObject>::call_slot (const boost::function<void()>& f)
}
req->the_slot = f;
+#ifndef NDEBUG
+ if (getenv ("DEBUG_THREADED_SIGNALS")) {
+ std::cerr << "functor called in wrong thread for " << name() << " (from " << pthread_name() << ") send request ...\n";
+ }
+#endif
send_request (req);
}
diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h
index 39fe83b0fe..d04d62c463 100644
--- a/libs/pbd/pbd/abstract_ui.h
+++ b/libs/pbd/pbd/abstract_ui.h
@@ -24,12 +24,11 @@
#include <string>
#include <pthread.h>
-#include <sigc++/sigc++.h>
-
#include <glibmm/thread.h>
#include "pbd/receiver.h"
#include "pbd/ringbufferNPT.h"
+#include "pbd/signals.h"
#include "pbd/base_ui.h"
class Touchable;
@@ -52,8 +51,8 @@ class AbstractUI : public BaseUI
Glib::Mutex request_buffer_map_lock;
RequestBufferMap request_buffers;
- Glib::Private<RequestBuffer> per_thread_request_buffer;
-
+ static Glib::StaticPrivate<RequestBuffer> per_thread_request_buffer;
+
Glib::Mutex request_list_lock;
std::list<RequestObject*> request_list;
@@ -62,6 +61,7 @@ class AbstractUI : public BaseUI
void send_request (RequestObject *);
virtual void do_request (RequestObject *) = 0;
+ PBD::ScopedConnection new_thread_connection;
};
#endif /* __pbd_abstract_ui_h__ */
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
index d94c58d54f..28dd4b7a31 100644
--- a/libs/pbd/pbd/controllable.h
+++ b/libs/pbd/pbd/controllable.h
@@ -73,7 +73,7 @@ class Controllable : public PBD::StatefulDestructible {
bool _touching;
static void add (Controllable&);
- static void remove (Controllable&);
+ static void remove (Controllable*);
typedef std::set<PBD::Controllable*> Controllables;
typedef std::map<std::string,PBD::Controllable*> ControllablesByURI;
diff --git a/libs/pbd/pbd/destructible.h b/libs/pbd/pbd/destructible.h
index 8cc0113ff7..8881b45c55 100644
--- a/libs/pbd/pbd/destructible.h
+++ b/libs/pbd/pbd/destructible.h
@@ -26,14 +26,13 @@ namespace PBD {
class Destructible {
public:
- Destructible() : refs_dropped (false){}
- virtual ~Destructible () {}
+ Destructible() {}
+ virtual ~Destructible () { Destroyed(); }
- PBD::Signal0<void> GoingAway;
- void drop_references () { if (!refs_dropped) { GoingAway(); } refs_dropped = true; }
+ PBD::Signal0<void> Destroyed;
+ PBD::Signal0<void> DropReferences;
- private:
- bool refs_dropped;
+ void drop_references () { DropReferences(); }
};
}
diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
index a08d3bb717..8c3d1a1870 100644
--- a/libs/pbd/pbd/memento_command.h
+++ b/libs/pbd/pbd/memento_command.h
@@ -42,7 +42,7 @@ public:
: obj(a_object), before(a_before), after(a_after)
{
/* if the object dies, make sure that we die and that everyone knows about it */
- obj.GoingAway.connect_same_thread (obj_death_connection, boost::bind (&MementoCommand::object_died, this));
+ obj.Destroyed.connect_same_thread (obj_death_connection, boost::bind (&MementoCommand::object_died, this));
}
~MementoCommand () {
diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h
index e6c5a376df..b8f99ba144 100644
--- a/libs/pbd/pbd/pthread_utils.h
+++ b/libs/pbd/pbd/pthread_utils.h
@@ -25,7 +25,7 @@
#include <string>
#include <stdint.h>
-#include <sigc++/sigc++.h>
+#include <pbd/signals.h>
int pthread_create_and_store (std::string name, pthread_t *thread, void * (*start_routine)(void *), void * arg);
void pthread_cancel_one (pthread_t thread);
@@ -36,10 +36,7 @@ std::string pthread_name ();
namespace PBD {
extern void notify_gui_about_thread_creation (std::string, pthread_t, std::string, int requests = 256);
- extern void notify_gui_about_thread_exit (pthread_t);
-
- extern sigc::signal<void,pthread_t> ThreadLeaving;
- extern sigc::signal<void,std::string,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
+ extern PBD::Signal4<void,std::string,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
}
#endif /* __pbd_pthread_utils__ */
diff --git a/libs/pbd/pbd/signals.h b/libs/pbd/pbd/signals.h
index 0b44ee8051..ffb0dcebb6 100644
--- a/libs/pbd/pbd/signals.h
+++ b/libs/pbd/pbd/signals.h
@@ -102,6 +102,8 @@ public:
typename SignalType::result_type operator()() {
return _signal ();
}
+
+ bool empty() const { return _signal.empty(); }
private:
SignalType _signal;
@@ -144,6 +146,8 @@ public:
return _signal (arg1);
}
+ bool empty() const { return _signal.empty(); }
+
private:
SignalType _signal;
};
@@ -184,6 +188,8 @@ public:
return _signal (arg1, arg2);
}
+ bool empty() const { return _signal.empty(); }
+
private:
SignalType _signal;
};
@@ -224,6 +230,50 @@ public:
return _signal (arg1, arg2, arg3);
}
+ bool empty() const { return _signal.empty(); }
+
+private:
+ SignalType _signal;
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4>
+class Signal4 {
+public:
+ Signal4 () {}
+ typedef boost::signals2::signal<R(A1,A2,A3,A4)> SignalType;
+
+ void connect_same_thread (ScopedConnectionList& clist,
+ const typename SignalType::slot_function_type& slot) {
+ clist.add_connection (_signal.connect (slot));
+ }
+
+ void connect_same_thread (Connection& c,
+ const typename SignalType::slot_function_type& slot) {
+ c = _signal.connect (slot);
+ }
+
+ static void compositor (typename boost::function<void(A1,A2,A3)> f, PBD::EventLoop* event_loop, A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
+ event_loop->call_slot (boost::bind (f, arg1, arg2, arg3, arg4));
+ }
+
+ void connect (ScopedConnectionList& clist,
+ const typename SignalType::slot_function_type& slot,
+ PBD::EventLoop* event_loop) {
+ clist.add_connection (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4)));
+ }
+
+ void connect (Connection& c,
+ const typename SignalType::slot_function_type& slot,
+ PBD::EventLoop* event_loop) {
+ c = _signal.connect (_signal.connect (boost::bind (&compositor, slot, event_loop, _1, _2, _3, _4)));
+ }
+
+ typename SignalType::result_type operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
+ return _signal (arg1, arg2, arg3, arg4);
+ }
+
+ bool empty() const { return _signal.empty(); }
+
private:
SignalType _signal;
};
diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc
index 495214a481..ca63603446 100644
--- a/libs/pbd/pthread_utils.cc
+++ b/libs/pbd/pthread_utils.cc
@@ -33,11 +33,9 @@ using namespace std;
typedef std::map<string,pthread_t> ThreadMap;
static ThreadMap all_threads;
static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t gui_notify_lock = PTHREAD_MUTEX_INITIALIZER;
namespace PBD {
- sigc::signal<void,pthread_t> ThreadLeaving;
- sigc::signal<void,std::string, pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
+ PBD::Signal4<void,std::string, pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize;
}
using namespace PBD;
@@ -54,17 +52,7 @@ static int thread_creator (pthread_t* thread_id, const pthread_attr_t* attr, voi
void
PBD::notify_gui_about_thread_creation (std::string target_gui, pthread_t thread, std::string str, int request_count)
{
- pthread_mutex_lock (&gui_notify_lock);
ThreadCreatedWithRequestSize (target_gui, thread, str, request_count);
- pthread_mutex_unlock (&gui_notify_lock);
-}
-
-void
-PBD::notify_gui_about_thread_exit (pthread_t thread)
-{
- pthread_mutex_lock (&gui_notify_lock);
- ThreadLeaving (thread);
- pthread_mutex_unlock (&gui_notify_lock);
}
int
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index 81e31f3a88..c3594b1658 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -83,7 +83,7 @@ UndoTransaction::add_command (Command *const action)
so there is no need to manage this connection.
*/
- action->GoingAway.connect_same_thread (*this, boost::bind (&command_death, this, action));
+ action->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, action));
actions.push_back (action);
}
@@ -186,7 +186,7 @@ UndoHistory::add (UndoTransaction* const ut)
{
uint32_t current_depth = UndoList.size();
- ut->GoingAway.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut));
+ ut->DropReferences.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut));
/* if the current undo history is larger than or equal to the currently
requested depth, then pop off at least 1 element to make space
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc
index 6054d01334..9e64667ce7 100644
--- a/libs/surfaces/osc/osc.cc
+++ b/libs/surfaces/osc/osc.cc
@@ -578,7 +578,7 @@ OSC::listen_to_route (boost::shared_ptr<Route> route, lo_address addr)
*/
if (!route_exists) {
- route->GoingAway.connect (*this, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this);
+ route->DropReferences.connect (*this, boost::bind (&OSC::drop_route, this, boost::weak_ptr<Route> (route)), this);
}
}