diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-22 20:21:43 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-12-22 20:21:43 +0000 |
commit | c83389b8ec5fef9553a401e6123b7e55702af9e2 (patch) | |
tree | 5580dd13b6275eefe67b9147ce96fa10db4d8674 /libs/pbd/pbd | |
parent | 87fb46859c5950af7c00111afa81a00a1fad2196 (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.cc | 26 | ||||
-rw-r--r-- | libs/pbd/pbd/abstract_ui.h | 8 | ||||
-rw-r--r-- | libs/pbd/pbd/controllable.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/destructible.h | 11 | ||||
-rw-r--r-- | libs/pbd/pbd/memento_command.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/pthread_utils.h | 7 | ||||
-rw-r--r-- | libs/pbd/pbd/signals.h | 50 |
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; }; |