summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd
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/pbd/pbd
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/pbd/pbd')
-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
7 files changed, 87 insertions, 19 deletions
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;
};