2 Copyright (C) 2009-2012 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __pbd_signals_h__
21 #define __pbd_signals_h__
24 #include <glibmm/thread.h>
26 #include <boost/noncopyable.hpp>
27 #include <boost/bind.hpp>
28 #include <boost/bind/protect.hpp>
29 #include <boost/function.hpp>
30 #include <boost/thread/mutex.hpp>
31 #include <boost/enable_shared_from_this.hpp>
32 #include <boost/optional.hpp>
34 #include "pbd/event_loop.h"
43 virtual ~SignalBase () {}
44 virtual void disconnect (boost::shared_ptr<Connection>) = 0;
50 class Connection : public boost::enable_shared_from_this<Connection>
53 Connection (SignalBase* b) : _signal (b) {}
57 boost::mutex::scoped_lock lm (_mutex);
59 _signal->disconnect (shared_from_this ());
63 void signal_going_away ()
65 boost::mutex::scoped_lock lm (_mutex);
75 class OptionalLastValue
78 typedef boost::optional<R> result_type;
80 template <typename Iter>
81 result_type operator() (Iter first, Iter last) const {
83 while (first != last) {
92 typedef boost::shared_ptr<Connection> UnscopedConnection;
94 class ScopedConnection
97 ScopedConnection () {}
98 ScopedConnection (UnscopedConnection c) : _c (c) {}
99 ~ScopedConnection () {
110 ScopedConnection& operator= (UnscopedConnection const & o)
117 UnscopedConnection _c;
120 class ScopedConnectionList : public boost::noncopyable
123 ScopedConnectionList();
124 virtual ~ScopedConnectionList ();
126 void add_connection (const UnscopedConnection& c);
127 void drop_connections ();
130 /* this class is not copyable */
131 ScopedConnectionList(const ScopedConnectionList&);
133 /* this lock is shared by all instances of a ScopedConnectionList.
134 We do not want one mutex per list, and since we only need the lock
135 when adding or dropping connections, which are generally occuring
136 in object creation and UI operations, the contention on this
137 lock is low and not of significant consequence. Even though
138 boost::signals2 is thread-safe, this additional list of
139 scoped connections needs to be protected in 2 cases:
141 (1) (unlikely) we make a connection involving a callback on the
142 same object from 2 threads. (wouldn't that just be appalling
145 (2) where we are dropping connections in one thread and adding
149 static Glib::StaticMutex _lock;
151 typedef std::list<ScopedConnection*> ConnectionList;
152 ConnectionList _list;
155 #include "pbd/signals_generated.h"
159 #endif /* __pbd_signals_h__ */