X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fpbd%2Fsignals.h;h=df4c9cef29331c5d3b0477143d932e0c7fc4df8e;hb=d19ec8ba46274bd41c251f81e63503183db15f08;hp=904d51e45f472abe6a1385904f029309c7364ac5;hpb=32bed9aaf040cbd06f9855b568c14cb7a7050d58;p=ardour.git diff --git a/libs/pbd/pbd/signals.h b/libs/pbd/pbd/signals.h index 904d51e45f..df4c9cef29 100644 --- a/libs/pbd/pbd/signals.h +++ b/libs/pbd/pbd/signals.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2012 Paul Davis + Copyright (C) 2009-2012 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,59 +20,104 @@ #ifndef __pbd_signals_h__ #define __pbd_signals_h__ +#include + #include -#include +#include + +#ifdef nil +#undef nil +#endif + +#include #include #include #include #include -#include #include #include +#include "pbd/libpbd_visibility.h" #include "pbd/event_loop.h" +#ifndef NDEBUG +#define DEBUG_PBD_SIGNAL_CONNECTIONS +#endif + +#ifdef DEBUG_PBD_SIGNAL_CONNECTIONS +#include "pbd/stacktrace.h" +#include +#endif + namespace PBD { -class Connection; +class LIBPBD_API Connection; -class SignalBase +class LIBPBD_API SignalBase { public: + SignalBase () +#ifdef DEBUG_PBD_SIGNAL_CONNECTIONS + : _debug_connection (false) +#endif + {} virtual ~SignalBase () {} virtual void disconnect (boost::shared_ptr) = 0; +#ifdef DEBUG_PBD_SIGNAL_CONNECTIONS + void set_debug_connection (bool yn) { _debug_connection = yn; } +#endif protected: - boost::mutex _mutex; + mutable Glib::Threads::Mutex _mutex; +#ifdef DEBUG_PBD_SIGNAL_CONNECTIONS + bool _debug_connection; +#endif }; -class Connection : public boost::enable_shared_from_this +class LIBPBD_API Connection : public boost::enable_shared_from_this { public: - Connection (SignalBase* b) : _signal (b) {} + Connection (SignalBase* b, PBD::EventLoop::InvalidationRecord* ir) : _signal (b), _invalidation_record (ir) + { + if (_invalidation_record) { + _invalidation_record->ref (); + } + } void disconnect () { - boost::mutex::scoped_lock lm (_mutex); + Glib::Threads::Mutex::Lock lm (_mutex); if (_signal) { _signal->disconnect (shared_from_this ()); - } + _signal = 0; + } + } + + void disconnected () + { + if (_invalidation_record) { + _invalidation_record->unref (); + } } void signal_going_away () { - boost::mutex::scoped_lock lm (_mutex); + Glib::Threads::Mutex::Lock lm (_mutex); + if (_invalidation_record) { + _invalidation_record->unref (); + } _signal = 0; } private: - boost::mutex _mutex; + Glib::Threads::Mutex _mutex; SignalBase* _signal; + PBD::EventLoop::InvalidationRecord* _invalidation_record; }; template -class OptionalLastValue +class /*LIBPBD_API*/ OptionalLastValue { public: typedef boost::optional result_type; @@ -88,10 +133,10 @@ public: return r; } }; - + typedef boost::shared_ptr UnscopedConnection; - -class ScopedConnection + +class LIBPBD_API ScopedConnection { public: ScopedConnection () {} @@ -109,6 +154,11 @@ public: ScopedConnection& operator= (UnscopedConnection const & o) { + if (_c == o) { + return *this; + } + + disconnect (); _c = o; return *this; } @@ -116,13 +166,13 @@ public: private: UnscopedConnection _c; }; - -class ScopedConnectionList : public boost::noncopyable + +class LIBPBD_API ScopedConnectionList : public boost::noncopyable { public: ScopedConnectionList(); virtual ~ScopedConnectionList (); - + void add_connection (const UnscopedConnection& c); void drop_connections (); @@ -134,21 +184,21 @@ class ScopedConnectionList : public boost::noncopyable scoped connections needs to be protected in 2 cases: (1) (unlikely) we make a connection involving a callback on the - same object from 2 threads. (wouldn't that just be appalling + same object from 2 threads. (wouldn't that just be appalling programming style?) - + (2) where we are dropping connections in one thread and adding one from another. */ - Glib::Mutex _lock; + Glib::Threads::Mutex _lock; typedef std::list ConnectionList; ConnectionList _list; }; -#include "pbd/signals_generated.h" - +#include "pbd/signals_generated.h" + } /* namespace */ #endif /* __pbd_signals_h__ */