c++-gtk-utils
emitter.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 to 2011 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36 
37 */
38 
39 #ifndef CGU_EMITTER_H
40 #define CGU_EMITTER_H
41 
42 /**
43  * @file emitter.h
44  * @brief This file provides a thread-safe signal/slot mechanism, with
45  * automatic disconnection.
46  *
47  * An EmitterArg object is a list of Callback::FunctorArg objects.
48  * Callback::FunctorArg objects may be "connected" to the EmitterArg
49  * object, and all functors so connected will be executed when the
50  * operator()() or emit() member functions of the EmitterArg object
51  * concerned is called. They will be called in the order in which
52  * they were connected. Emitter is a typedef for EmitterArg<>. The
53  * generalised EmitterArg<T...> type contains
54  * Callback::FunctorArg<T...> objects (types T... being the unbound
55  * arguments of a Callback::CallbackArg<T...> callback - see
56  * Cgu::Callback for further details, and "Usage" below for examples.)
57  * The Emitter type holds Callback::Functor (namely
58  * Callback::FunctorArg<>) objects.
59  *
60  * The main advantage of an emitter object as opposed to storing a
61  * functor object directly, apart from the fact that more than one
62  * functor can be dispatched by a single call to EmitterArg::emit() or
63  * EmitterArg::operator()(), is that it provides for automatic
64  * disconnection of a functor if the object whose member function it
65  * represents has ceased to exist.
66  *
67  * Where automatic disconnection is wanted, the object whose method is
68  * to be encapsulated by a functor must have a Releaser object as a
69  * public member function. The Releaser object should be passed as
70  * the second argument of EmitterArg::connect(). As well as a
71  * Releaser object informing an emitter object when it has ceased to
72  * exist, an emitter object will do the same to the Releaser object if
73  * the emitter object happens to be destroyed before an object whose
74  * members it references (and therefore before the Releaser object).
75  * Automatic disconnection is mainly useful for non-static member
76  * functions, but it can be employed for static member functions or
77  * non-member functions if wanted (that will in effect bind the
78  * lifetime of the functor to that of the object to whose Releaser the
79  * functor has been attached.)
80  *
81  * It is safe for a connected function (i) to delete the EmitterArg
82  * object to which it is connected, even if there are other functors
83  * still to execute in the same emission (which will execute normally
84  * provided they do not try to call any of the emitter's functions),
85  * (ii) to call 'delete this' nothwithstanding that the connected
86  * function is protected by a Releaser object (assuming all the other
87  * restraints on calling 'delete this' are met), provided that no
88  * other access would be made to the deleted object in a function call
89  * connected to the same emitter which is due to execute subsequently
90  * in the same emission, and (iii) to disconnect itself from the
91  * EmitterArg object. This design approach has a trade-off: if a
92  * connected function tries to block, unblock or disconnect another
93  * function connected to the same EmitterArg object which is due to
94  * execute subsequently in the same emission (or to block, unblock or
95  * disconnect itself when it is due to execute again subsequently in
96  * the same emission), the attempted block, unblock or disconnection
97  * will not have any effect on that emission (it will only have effect
98  * on a subsequent emission). In addition, a connected function may
99  * not destroy an object whose non-static method is connected to the
100  * same emitter and which would execute subsequently in the same
101  * emission, even if that object is protected by a Releaser object
102  * (the non-static method will unsuccessfully attempt to execute
103  * notwithstanding the destruction of the object it would be operating
104  * on).
105  *
106  * The SafeEmitterArg classes are the same as their EmitterArg
107  * counterparts except that they contain Callback::SafeFunctorArg
108  * objects, and their emit(), operator()(), connect(), disconnect(),
109  * block(), unblock() and destructor methods are protected by a mutex
110  * so that different threads can call these methods on the same
111  * emitter object, or create and delete the object.
112  *
113  * Note that the mutexes are released when the operator()()/emit()
114  * methods of the relevent Callback::SafeFunctorArg objects are
115  * called, as SafeEmitterArg objects have no idea what the referenced
116  * callbacks will do so if they were not released deadlocks could
117  * arise from recursive or out-of-order locking of the SafeEmitterArg
118  * mutex. It is therefore for users to provide additional
119  * synchronisation if the functions encapsulated by the relevant
120  * functors themselves need additional protection. Note also the
121  * subsidiary thread-safety points mentioned below.
122  *
123  * The Releaser class is intrinsically thread safe (the overhead of
124  * locking is so low that it is pointless having a separate
125  * unprotected class). This means that if a program is
126  * multi-threaded, you can use the plain EmitterArg classes provided
127  * that only the thread which creates a particular EmitterArg object
128  * calls connect(), block(), unblock((), emit() or operator()() on it,
129  * or deletes it, or calls disconnect() on it (either directly or
130  * through a Releaser object being destroyed). Where more than one
131  * thread might do that in relation to any one emitter object, use
132  * SafeEmitterArg.
133  *
134  * Alternatives
135  * ------------
136  *
137  * These classes are intended as a lightweight thread-safe signal/slot
138  * mechanism for GUI programming. For more demanding usage libsigc++
139  * is a good choice, except that it is not thread-safe. An
140  * alternative to libsigc++ is the boost::signal2 module, which is
141  * thread-safe.
142  *
143  * Subsidiary thread-safety points
144  * -------------------------------
145  *
146  * As mentioned, the SafeEmitterArg classes are thread safe, and their
147  * methods can be called in different threads without ill effect.
148  * However, there are some things that cannot be done. Users should
149  * observe two points.
150  *
151  * First, it has been mentioned that if a connected function blocks,
152  * unblocks or disconnects another function connected to the same
153  * emitter object and due to execute subsequently in the same
154  * emission, the blocking, unblocking or disconnection will not have
155  * effect in that emission, and that a connected function may not
156  * delete an object whose non-static method is due to execute
157  * subsequently in the same emission. The same outcome would result
158  * if another thread tries to do any of these things while an emission
159  * is under way. Another thread should therefore leave alone objects
160  * connected to a SafeEmitterArg object from the time of operator()()
161  * or emit() beginning to the time of it ending, and not try to
162  * interfere.
163  *
164  * Secondly, when a Releaser object is passed as the second argument
165  * to the connect() method of a SafeEmitterArg object, the Releaser
166  * object must remain in existence until the connect() method returns
167  * or the emitter may be left in an inconsistent state.
168  *
169  * @anchor AssignmentAnchor
170  * Assignment
171  * ----------
172  *
173  * EmitterArg and SafeEmitterArg objects cannot be copied. Releaser
174  * objects can be (we do not want to make a class uncopiable just
175  * because it has the safety feature of having a Releaser object as a
176  * member).
177  *
178  * So how should assignment of a Releaser object and of a class which
179  * has a Releaser as a member be handled? An object which has a
180  * Releaser as a member and which is being assigned to (the assignee)
181  * could keep all its existing pre-assignment emitter connections - so
182  * far as the Releaser object is concerned, it will have to do so
183  * where the connections are not protected by the Releaser object, and
184  * we could do the same in relation to protected connections, in which
185  * case we would make operator=() of Releaser do nothing: that is,
186  * just return - a default assignment would always be wrong as it
187  * would take the assignor's Releaser state but inherit none of its
188  * connections, which the assignee cannot inherit as they depend on a
189  * remote emitter object or objects.
190  *
191  * However, the state of the assignee after assignment may not be such
192  * as to permit the inheriting of all the assignor's state except its
193  * connections. Accordingly, the default strategy adopted here is for
194  * the Releaser object to become a blank sheet on assignment. After
195  * assignment, an assignee which has a Releaser object as a member
196  * will no longer have any of the emitter connections which were,
197  * prior to assignment, protected by the Releaser object. If in a
198  * particular case the user does not want this behaviour, she should
199  * provide an assignment operator in the class which has Releaser as a
200  * member and leave Releaser alone in the assignment operator.
201  *
202  * Usage
203  * -----
204  *
205  * For an object my_obj of class type MyClass, with a method void
206  * MyClass::my_method(int, int, const char*), usage for a fully bound
207  * functor and emitter would be:
208  *
209  * @code
210  * using namespace Cgu;
211  * int arg1 = 1, arg2 = 5;
212  * Emitter e;
213  * e.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
214  * e();
215  *
216  * SafeEmitter se;
217  * se.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
218  * se();
219  * @endcode
220  *
221  * Or for a partially bound functor and emitter:
222  *
223  * @code
224  * using namespace Cgu;
225  * int arg1 = 1, arg2 = 5;
226  * EmitterArg<int, const char*> e;
227  * e.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
228  * e(arg2, "Hello\n");
229  *
230  * SafeEmitterArg<int, const char*> se;
231  * se.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
232  * se(arg2, "Hello\n");
233  * @endcode
234  *
235  * EmitterArg classes do not provide for a return value. If a
236  * result is wanted, users should pass an unbound argument by
237  * reference or pointer (or pointer to pointer).
238  *
239  * CallbackArg (and so FunctorArg and EmitterArg) objects can be
240  * constructed for up to three bound arguments and an unlimited number
241  * of unbound arguments, or from std::function objects (in which case
242  * there is no limit to the number of bound arguments nor their
243  * ordering with unbound arguments). See Cgu::Callback for further
244  * details.
245  *
246  * Exception safety
247  * ----------------
248  *
249  * Apart from the emit()/operator()() and connect() methods, nothing
250  * done to an EmitterArg/SafeEmitterArg object should cause an
251  * exception to be thrown. This is because other methods only iterate
252  * through a std::list object using std::for_each(), std::find() or by
253  * hand, and the only things done by std::for_each() or after a
254  * std::find() or iteration is to remove a functor from the list
255  * (copying a functor and comparing functors never throw, nor does
256  * destroying a functor provided the destructors of any bound argument
257  * type do not throw). Thus, an EmitterArg/SafeEmitterArg and
258  * Releaser object should never get into an inconsistent state.
259  *
260  * The connect() method could throw a std::bad_alloc exception, either
261  * on creating new functors or on pushing the functors onto the list.
262  * However, were it to do so, the method has strong exception safety
263  * (assuming merely iterating over a list does not throw, as it should
264  * not).
265  *
266  * The emit()/operator()() methods could throw std::bad_alloc, and so
267  * far as that is concerned emission of all the connected functions
268  * will either all succeed or all fail. In addition, the connected
269  * functions referenced by the functors held by the emitter might
270  * throw when executed. emit()/operator()() do not attempt to catch
271  * these exceptions as there is nothing they could do with them. This
272  * means that although a throwing connected function will not leave
273  * the EmitterArg/SafeEmitterArg object in an inconsistent state, any
274  * other connected functions due to execute subsequently on that same
275  * emission will not execute. If that is important in any particular
276  * case, the user must incorporate logic in the connected functions to
277  * cater for an exception causing only part execution, or must connect
278  * only one function to any one signal and "chain" emissions by hand
279  * so as to do the right thing.
280  */
281 
282 /*
283  Mutex locking heirarchy:
284 
285  Some out-of-order locking must take place because of the
286  relationship between the Releaser and SafeEmitterArg<> classes. The
287  mutex of Releaser is given the higher priority. This means that a
288  plain EmitterArg<> object will not take any hit from the fact that
289  Releaser is also useable with SafeEmitterArg<> objects.
290 
291  One consequence is that to avoid deadlocks, it is the
292  SafeEmitterArg<> functions which must yield when a deadlock would
293  otherwise arise. Yielding could occur in
294  SafeEmitterArg<>::~SafeEmitterArg() and
295  SafeEmitterArg<>::disconnect().
296 */
297 
298 #ifdef CGU_USE_SCHED_YIELD
299 #include <sched.h>
300 #else
301 #include <unistd.h>
302 #endif
303 
304 #include <list>
305 #include <unordered_set>
306 #include <algorithm>
307 #include <functional>
308 
309 #include <c++-gtk-utils/callback.h>
310 #include <c++-gtk-utils/mutex.h>
312 
313 namespace Cgu {
314 
315 /* The four basic emitter types */
316 
317 template <class... FreeArgs> class EmitterArg;
318 template <class... FreeArgs> class SafeEmitterArg;
319 typedef EmitterArg<> Emitter;
321 
322 /**
323  * @class Releaser emitter.h c++-gtk-utils/emitter.h
324  * @brief A class used for tracking EmitterArg and SafeEmitterArg
325  * connections.
326  * @sa EmitterArg SafeEmitterArg
327  * @sa emitter.h
328  * @sa Callback namespace
329  *
330  * This class provides tracking of EmitterArg and SafeEmitterArg
331  * connections. It should be a public member of any target class
332  * which wants functors representing any of its methods to be
333  * disconnected automatically from an EmitterArg or SafeEmitterArg
334  * object when the target class object is destroyed, and is passed as
335  * one of the arguments to the connect() method of EmitterArg or
336  * SafeEmitterArg.
337  *
338  * All its methods are thread-safe.
339  *
340  * For further background, read this: emitter.h
341  */
342 
343 class Releaser {
344 
345  // from version 2.0.0-rc3 we use std::unordered_set rather than
346  // std::list in Releaser. We can't do that for
347  // EmitterArg/SafeEmitterArg objects, as they need to execute
348  // connected functors in the order in which they were connected.
349  std::unordered_set<Callback::SafeFunctor> disconnect_set;
350  Thread::Mutex mutex;
351 
352  // only an EmitterArg or SafeEmitterArg object can access add(), remove and try_remove()
353  void add(const Callback::SafeFunctor&);
354  void remove(const Callback::SafeFunctor&);
355  void try_remove(const Callback::SafeFunctor&, int*);
356 public:
357  template <class... T> friend class EmitterArg;
358  template <class... T> friend class SafeEmitterArg;
359 
360  // operator=() and the copy constructor should copy nothing from the
361  // assignor, because disconnect_set should be empty in the
362  // assignee, as any class containing us does not acquire as assignee
363  // any emitter functors representing any of its methods
364 
365 /**
366  * See notes on @ref AssignmentAnchor "assignment" to see how this
367  * operates. This does not throw provided that the destructors of any
368  * bound arguments of a functor managed by this Releaser object prior
369  * to assignment do not throw (as they should not do), and assuming
370  * that merely iterating through a list does not throw (as it would
371  * not on any sane implementation).
372  * @param r The assignee.
373  */
374  Releaser& operator=(const Releaser& r);
375 
376 /**
377  * This does not copy anything from the Releaser object passed as an
378  * argument - see the notes on @ref AssignmentAnchor "assignment" for
379  * an explanation of why. This does not throw.
380  * @param r A Releaser object.
381  * @exception std::bad_alloc This constructor might throw
382  * std::bad_alloc if memory is exhausted and the system throws in that
383  * case.
384  * @exception Thread::MutexError This constructor might throw
385  * Thread::MutexError if initialisation of the contained mutex fails.
386  * (It is often not worth checking for this, as it means either memory
387  * is exhausted or pthread has run out of other resources to create
388  * new mutexes.)
389  */
390  Releaser(const Releaser& r) {}
391 
392 /**
393  * @exception std::bad_alloc The default constructor might throw
394  * std::bad_alloc if memory is exhausted and the system throws in that
395  * case.
396  * @exception Thread::MutexError The default constructor might throw
397  * Thread::MutexError if initialisation of the contained mutex fails.
398  * (It is often not worth checking for this, as it means either memory
399  * is exhausted or pthread has run out of other resources to create
400  * new mutexes.)
401  */
402  Releaser() = default;
403 
404 /**
405  * The destructor does not throw provided that the destructors of any
406  * bound arguments of a functor managed by this Releaser object do not
407  * throw (as they should not do), and assuming that merely iterating
408  * through an unordered_set does not throw (as it would not on any
409  * sane implementation).
410  */
411  ~Releaser();
412 
413 /* Only has effect if --with-glib-memory-slices-compat or
414  * --with-glib-memory-slices-no-compat option picked */
416 };
417 
418 /* the emitter classes */
419 
420 /**
421  * @class EmitterArg emitter.h c++-gtk-utils/emitter.h
422  * @brief A class to execute callbacks connected to it, with provision
423  * for automatic disconnection.
424  * @sa SafeEmitterArg Releaser
425  * @sa emitter.h
426  * @sa Callback namespace
427  *
428  * Callback::FunctorArg objects may be connected to Emitter classes,
429  * and will be executed when EmitterArg::emit() or
430  * EmitterArg::operator()() are called.
431  *
432  * One version of the connect() method takes a Releaser object as an
433  * argument. Such a Releaser object should be a public member of any
434  * target class which wants functors representing any of its methods
435  * to be disconnected automatically from the EmitterArg object when
436  * the target class object is destroyed.
437  *
438  * A connection may be explicitly disconnected by calling the
439  * disconnect() method, and may also be temporarily blocked and
440  * subsequently unblocked with the block() and unblock() methods.
441  *
442  * The template types are the types of the unbound arguments, if any.
443  * EmitterArg<> is typedef'ed to Emitter.
444  *
445  * @b Usage
446  *
447  * For a class my_obj of type MyClass, with a method void
448  * MyClass::my_method(int, int, const char*), usage for a fully bound functor
449  * and emitter would be:
450  *
451  * @code
452  * using namespace Cgu;
453  * int arg1 = 1, arg2 = 5;
454  * Emitter e;
455  * e.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
456  * e();
457  * @endcode
458  *
459  * Or for a partially bound functor and emitter:
460  *
461  * @code
462  * using namespace Cgu;
463  * int arg1 = 1, arg2 = 5;
464  * EmitterArg<int, const char*> e;
465  * e.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
466  * e(arg2, "Hello\n");
467  * @endcode
468  *
469  * For further background, including about thread-safety and exception
470  * safety and other matters, read this: emitter.h, or for more
471  * information about bound and unbound arguments, read this:
472  * Cgu::Callback.
473  */
474 
475 template <class... FreeArgs>
476 class EmitterArg {
477 
478 #ifndef DOXYGEN_PARSING
479  // f1 is the functor we execute when we emit()
480  // f2 is the functor we execute in our destructor if we are destroyed
481  // before the remote object is
482  struct ListItem {
483  Callback::FunctorArg<FreeArgs...> f1;
485  bool blocked;
486  ListItem(Callback::FunctorArg<FreeArgs...> f1_, Callback::Functor f2_):
487  f1(f1_), f2(f2_), blocked(false) {}
488  };
489 #endif
490 
491  std::list<ListItem> emission_list;
492 
493  // only Releaser objects can access this
494  void tracking_disconnect(const Callback::FunctorArg<FreeArgs...>&);
495 
496 public:
497  friend class Releaser;
498 
499 /**
500  * This will execute the connected functors.
501  * @param args The unbound arguments to be passed to the referenced
502  * function or class method, if any.
503  * @exception std::bad_alloc The method might throw std::bad_alloc if
504  * memory is exhausted and the system throws in that case. In
505  * addition, it will throw if the functions or class methods
506  * referenced by the functors throw (or if the copy constructor of a
507  * free or bound argument throws and it is not a reference argument).
508  */
509  void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {emit(args...);}
510 
511 /**
512  * This will execute the connected functors.
513  * @param args The unbound arguments to be passed to the referenced
514  * function or class method, if any.
515  * @exception std::bad_alloc The method might throw std::bad_alloc if
516  * memory is exhausted and the system throws in that case. In
517  * addition, it will throw if the functions or class methods
518  * referenced by the functors throw (or if the copy constructor of a
519  * free or bound argument throws and it is not a reference argument).
520  */
521  void emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
522 
523 /**
524  * This will execute the connected functors, but it also reports
525  * whether in fact there were any connected functors to execute. (It
526  * is not necessary to use this function just because it is not known
527  * whether a functor is connected - if the standard emit() function is
528  * called when no functor is connected, nothing will happen. The
529  * feature of this method is that it will report the outcome.)
530  * @param args The unbound arguments to be passed to the connected
531  * functions or class methods, if any.
532  * @return Returns false if there were no functors to execute, or true
533  * if functors have been executed.
534  * @exception std::bad_alloc The method might throw std::bad_alloc if
535  * memory is exhausted and the system throws in that case. In
536  * addition, it will throw if the functions or class methods
537  * referenced by the functors throw (or if the copy constructor of a
538  * free or bound argument throws and it is not a reference argument).
539  */
540  bool test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
541 
542 /**
543  * Connects a functor.
544  * @param f The functor to connect.
545  * @return The functor connected.
546  * @exception std::bad_alloc The method might throw std::bad_alloc if
547  * memory is exhausted and the system throws in that case.
548  */
550 
551 /**
552  * Connects a functor.
553  * @param f The functor to connect.
554  * @param r A Releaser object for automatic disconnection of the
555  * functor if the object whose method it represents is destroyed.
556  * @return The functor connected.
557  * @exception std::bad_alloc The method might throw std::bad_alloc if
558  * memory is exhausted and the system throws in that case.
559  */
561 
562 /**
563  * Disconnects a functor previously connected. This does not throw
564  * provided that the destructors of any bound arguments do not throw
565  * (as they should not do), and assuming that merely iterating through
566  * a list does not throw (as it would not on any sane implementation).
567  * @param f The functor to disconnect.
568  * @note If the same functor has been connected more than once to the
569  * same EmitterArg object, this call will disconnect all of them.
570  */
572 
573 /**
574  * Blocks a connected functor from executing when emit() or
575  * operator()() is called until unblock() is called. This method does
576  * not throw (assuming that merely iterating through a list does not
577  * throw, as it would not on any sane implementation).
578  * @param f The functor to block.
579  * @note If the same functor has been connected more than once to the
580  * same EmitterArg object, this call will block all of them.
581  */
583 
584 /**
585  * Unblocks a previously blocked functor. This method does not throw
586  * (assuming that merely iterating through a list does not throw, as
587  * it would not on any sane implementation).
588  * @param f The functor to unblock.
589  * @note If the same functor has been connected more than once to the
590  * same EmitterArg object, this call will unblock all of them.
591  */
593 
594 /**
595  * @exception std::bad_alloc The constructor might throw
596  * std::bad_alloc if memory is exhausted and the system throws in that
597  * case.
598  */
599  EmitterArg() = default;
600 
601 /**
602  * This class cannot be copied. The copy constructor is deleted.
603  */
604  EmitterArg(const EmitterArg&) = delete;
605 
606 /**
607  * This class cannot be copied. The assignment operator is deleted.
608  */
609  EmitterArg& operator=(const EmitterArg&) = delete;
610 
611 /**
612  * The destructor does not throw provided that the destructors of any
613  * bound arguments do not throw (as they should not do), and assuming
614  * that merely iterating through a list does not throw (as it would
615  * not on any sane implementation).
616  */
617  ~EmitterArg();
618 
619 /* Only has effect if --with-glib-memory-slices-compat or
620  * --with-glib-memory-slices-no-compat option picked */
622 };
623 
624 template <class... FreeArgs>
626 
627  // gcc-4.4 and 4.5 don't support this:
628  /*
629  for(const ListItem& l: emission_list) {l.f2();}
630  */
631  // gcc-4.4 doesn't support this;
632  /*
633  std::for_each(emission_list.begin(), emission_list.end(),
634  [](const ListItem& l){(l.f2)();});
635  */
636  // So do it the old way:
637  struct DisconnectReleaserItem {
638  static void exec(const ListItem& l) {(l.f2)();}
639  };
640  std::for_each(emission_list.begin(), emission_list.end(),
641  DisconnectReleaserItem::exec);
642 }
643 
644 template <class... FreeArgs>
646 
647  // create a local copy of emission_list, to enable a connected
648  // function (i) to delete the EmitterArg<> object to which it is
649  // connected, even if there are other functors still to execute in
650  // the same emission (which will execute normally provided they do
651  // not try to call any of the emitter's functions), (ii) to call
652  // 'delete this' nothwithstanding that the connected function is
653  // protected by a Releaser object (assuming all the other restraints
654  // on calling 'delete this' are met), provided that no other access
655  // would be made to the deleted object in a function call connected
656  // to the same emitter which is due to execute subsequently in the
657  // same emission, and (iii) to disconnect itself from the
658  // EmitterArg object. This design approach has a trade-off: if a
659  // connected function tries to block, unblock or disconnect another
660  // function connected to the same EmitterArg<> object which is due
661  // to execute subsequently in the same emission (or to block,
662  // unblock or disconnect itself when it is due to execute again
663  // subsequently in the same emission), the attempted block, unblock
664  // or disconnection will not have any effect on that emission (it
665  // will only have effect on a subsequent emission). In addition, a
666  // connected function may not destroy an object whose non-static
667  // method is connected to the same emitter and which would execute
668  // subsequently in the same emission, even if that object is
669  // protected by a Releaser object (the non-static method will
670  // unsuccessfully attempt to execute notwithstanding the destruction
671  // of the object it would be operating on).
672 
673  // we can't use uniform initialisation here as it would be
674  // construed as invoking an initialiser list with a list item,
675  // rather than passing an already formed list
676  std::list<ListItem> local_list = emission_list;
677 
678 /*
679  gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
680  captures which comprise variadic arguments, and neither support
681  range-based for, so iterate by hand
682 */
683  typename std::list<ListItem>::const_iterator iter;
684  for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
685  if (!iter->blocked) iter->f1(args...);
686  }
687 }
688 
689 template <class... FreeArgs>
691  if (emission_list.empty()) return false;
692  emit(args...);
693  return true;
694 }
695 
696 template <class... FreeArgs>
698  emission_list.push_back(ListItem{f1, Callback::Functor()});
699  return f1;
700 }
701 
702 template <class... FreeArgs>
704  // In this method:
705  // f1 is the functor we execute when we emit()
706  // f2 is the functor we execute in our destructor if we are destroyed before the
707  // remote object is
708  // f3 is the functor the remote object executes in its Releaser if it is destroyed
709  // before we are, or if Releaser::operator=() is called
710 
712  Callback::Functor f2{Callback::make_ref(r, &Releaser::remove, f3)};
713  r.add(f3);
714  try {
715  emission_list.push_back(ListItem{f1, f2});
716  }
717  catch (...) {
718  r.remove(f3);
719  throw;
720  }
721  return f1;
722 }
723 
724 template <class... FreeArgs>
726  // in theory, we could have connected the same functor object
727  // more than once, so cater for that
728  auto iter = emission_list.begin();
729  for (;;) {
730  // gcc-4.4 doesn't support lambdas:
731  /*
732  iter = std::find_if(iter, emission_list.end(),
733  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
734  */
735  // so use a local struct and std::bind:
736  struct Pred {
737  static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
738  return (p.f1 == f);
739  }
740  };
741  iter = std::find_if(iter, emission_list.end(),
742  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
743  if (iter != emission_list.end()) {
744  // remove ourselves from the remote Releaser object
745  (iter->f2)();
746 
747  // remove this item from emission_list
748  iter = emission_list.erase(iter);
749  }
750  else break;
751  }
752 }
753 
754 // tracking disconnect() is the same as disconnect(), except that we do not
755 // execute f2 as the remote Releaser object will destroy its own functors
756 // in that case
757 template <class... FreeArgs>
759  auto iter = emission_list.begin();
760  for (;;) {
761  // gcc-4.4 doesn't support lambdas:
762  /*
763  iter = std::find_if(iter, emission_list.end(),
764  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
765  */
766  // so use a local struct and std::bind:
767  struct Pred {
768  static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
769  return (p.f1 == f);
770  }
771  };
772  iter = std::find_if(iter, emission_list.end(),
773  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
774  if (iter != emission_list.end()) {
775  // remove this item from emission_list
776  iter = emission_list.erase(iter);
777  }
778  else break;
779  }
780 }
781 
782 template <class... FreeArgs>
784  // in theory, we could have connected the same functor object
785  // more than once, so cater for that
786  auto iter = emission_list.begin();
787  for (;;) {
788  // gcc-4.4 doesn't support lambdas:
789  /*
790  iter = std::find_if(iter, emission_list.end(),
791  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
792  */
793  // so use a local struct and std::bind:
794  struct Pred {
795  static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
796  return (p.f1 == f);
797  }
798  };
799  iter = std::find_if(iter, emission_list.end(),
800  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
801  if (iter != emission_list.end()) {
802  iter->blocked = true;
803  ++iter;
804  }
805  else break;
806  }
807 }
808 
809 template <class... FreeArgs>
811  // in theory, we could have connected the same functor object
812  // more than once, so cater for that
813  auto iter = emission_list.begin();
814  for (;;) {
815  // gcc-4.4 doesn't support lambdas:
816  /*
817  iter = std::find_if(iter, emission_list.end(),
818  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
819  */
820  // so use a local struct and std::bind:
821  struct Pred {
822  static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
823  return (p.f1 == f);
824  }
825  };
826  iter = std::find_if(iter, emission_list.end(),
827  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
828  if (iter != emission_list.end()) {
829  iter->blocked = false;
830  ++iter;
831  }
832  else break;
833  }
834 }
835 
836 /**
837  * @class SafeEmitterArg emitter.h c++-gtk-utils/emitter.h
838  * @brief A thread-safe class to execute callbacks connected to it,
839  * with provision for automatic disconnection.
840  * @sa EmitterArg Releaser
841  * @sa emitter.h
842  * @sa Callback namespace
843  *
844  * This is a thread-safe version of the EmitterArg class.
845  * Callback::SafeFunctorArg objects may be connected to SafeEmitter
846  * classes, and will be executed when SafeEmitterArg::emit() or
847  * SafeEmitterArg::operator()() are called.
848  *
849  * One version of the connect() method takes a Releaser object as an
850  * argument. Such a Releaser object should be a public member of any
851  * target class which wants functors representing any of its methods
852  * to be disconnected automatically from the SafeEmitterArg object
853  * when the target class object is destroyed.
854  *
855  * A connection may be explicitly disconnected by calling the
856  * disconnect() method, and may also be temporarily blocked and
857  * subsequently unblocked with the block() and unblock() methods.
858  *
859  * The template types are the types of the unbound arguments, if any.
860  * SafeEmitterArg<> is typedef'ed to SafeEmitter.
861  *
862  * @b Usage
863  *
864  * For a class my_obj of type MyClass, with a method void
865  * MyClass::my_method(int, int, const char*), usage for a fully bound
866  * functor and emitter would be:
867  *
868  * @code
869  * using namespace Cgu;
870  * int arg1 = 1, arg2 = 5;
871  * SafeEmitter se;
872  * se.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
873  * se();
874  * @endcode
875  *
876  * Or for a partially bound functor and emitter:
877  *
878  * @code
879  * using namespace Cgu;
880  * int arg1 = 1, arg2 = 5;
881  * SafeEmitterArg<int, const char*> se;
882  * se.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
883  * se(arg2, "Hello\n");
884  * @endcode
885  *
886  * For further background, including about thread-safety and exception
887  * safety and other matters, read this: emitter.h, or for more
888  * information about bound and unbound arguments, read this:
889  * Cgu::Callback.
890  */
891 
892 template <class... FreeArgs>
893 class SafeEmitterArg {
894 
895 #ifndef DOXYGEN_PARSING
896  // f1 is the functor we execute when we emit()
897  // f2 is the functor we execute in our destructor if we are destroyed
898  // before the remote object is
899  struct ListItem {
900  Callback::SafeFunctorArg<FreeArgs...> f1;
902  bool blocked;
904  f1(f1_), f2(f2_), blocked(false) {}
905  };
906 #endif
907 
908  std::list<ListItem> emission_list;
909  mutable Thread::Mutex mutex; // make this mutable so we can lock/unlock in const methods
910 
911  // only Releaser objects can access this
912  void tracking_disconnect(const Callback::SafeFunctorArg<FreeArgs...>&);
913 
914 public:
915  friend class Releaser;
916 
917 /**
918  * This will execute the connected functors. It is thread safe if the
919  * functions or class methods referenced by the connected functors are
920  * thread safe.
921  * @param args The unbound arguments to be passed to the referenced
922  * function or class method, if any.
923  * @exception std::bad_alloc The method might throw std::bad_alloc if
924  * memory is exhausted and the system throws in that case. In
925  * addition, it will throw if the functions or class methods
926  * referenced by the functors throw (or if the copy constructor of a
927  * free or bound argument throws and it is not a reference argument).
928  */
929  void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {emit(args...);}
930 
931 /**
932  * This will execute the connected functors. It is thread safe if the
933  * functions or class methods referenced by the connected functors are
934  * thread safe.
935  * @param args The unbound arguments to be passed to the referenced
936  * function or class method, if any.
937  * @exception std::bad_alloc The method might throw std::bad_alloc if
938  * memory is exhausted and the system throws in that case. In
939  * addition, it will throw if the functions or class methods
940  * referenced by the functors throw (or if the copy constructor of a
941  * free or bound argument throws and it is not a reference argument).
942  */
943  void emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
944 
945 /**
946  * This will execute the connected functors, but it also reports
947  * whether in fact there were any connected functors to execute. It
948  * is thread safe if the functions or class methods referenced by the
949  * connected functors are thread safe. (It is not necessary to use
950  * this function just because it is not known whether a functor is
951  * connected - if the standard emit() function is called when no
952  * functor is connected, nothing will happen. The feature of this
953  * method is that it will report the outcome.)
954  * @param args The unbound arguments to be passed to the referenced
955  * function or class method, if any.
956  * @return Returns false if there were no functors to execute, or true
957  * if functors have been executed.
958  * @exception std::bad_alloc The method might throw std::bad_alloc if
959  * memory is exhausted and the system throws in that case. In
960  * addition, it will throw if the functions or class methods
961  * referenced by the functors throw (or if the copy constructor of a
962  * free or bound argument throws and it is not a reference argument).
963  */
964  bool test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
965 
966 /**
967  * Connects a functor. It is thread safe.
968  * @param f The functor to connect.
969  * @return The functor connected.
970  * @exception std::bad_alloc The method might throw std::bad_alloc if
971  * memory is exhausted and the system throws in that case.
972  */
974 
975 /**
976  * Connects a functor. It is thread safe.
977  * @param f The functor to connect.
978  * @param r A Releaser object for automatic disconnection of the
979  * functor if the object whose method it represents is destroyed.
980  * @return The functor connected.
981  * @exception std::bad_alloc The method might throw std::bad_alloc if
982  * memory is exhausted and the system throws in that case.
983  */
985 
986 /**
987  * Disconnects a functor previously connected. This does not throw
988  * provided that the destructors of any bound arguments do not throw
989  * (as they should not do), and assuming that merely iterating through
990  * a list does not throw (as it would not on any sane implementation).
991  * It is thread safe.
992  * @param f The functor to disconnect.
993  * @note If the same functor has been connected more than once to the
994  * same SafeEmitterArg object, this call will disconnect all of them.
995  */
997 
998 /**
999  * Blocks a connected functor from executing when emit() or
1000  * operator()() is called until unblock() is called. This method does
1001  * not throw (assuming that merely iterating through a list does not
1002  * throw, as it would not on any sane implementation). It is thread
1003  * safe.
1004  * @param f The functor to block.
1005  * @note If the same functor has been connected more than once to the
1006  * same SafeEmitterArg object, this call will block all of them.
1007  */
1009 
1010 /**
1011  * Unblocks a previously blocked functor. This method does not throw
1012  * (assuming that merely iterating through a list does not throw, as
1013  * it would not on any sane implementation). It is thread safe.
1014  * @param f The functor to unblock.
1015  * @note If the same functor has been connected more than once to the
1016  * same SafeEmitterArg object, this call will unblock all of them.
1017  */
1019 
1020 /**
1021  * @exception std::bad_alloc The constructor might throw
1022  * std::bad_alloc if memory is exhausted and the system throws in that
1023  * case.
1024  * @exception Thread::MutexError The constructor might throw
1025  * Thread::MutexError if initialisation of the contained mutex fails.
1026  * (It is often not worth checking for this, as it means either memory
1027  * is exhausted or pthread has run out of other resources to create
1028  * new mutexes.)
1029  */
1030  SafeEmitterArg() = default;
1031 
1032 /**
1033  * This class cannot be copied. The copy constructor is deleted.
1034  */
1035  SafeEmitterArg(const SafeEmitterArg&) = delete;
1036 
1037 /**
1038  * This class cannot be copied. The assignment operator is deleted.
1039  */
1040  SafeEmitterArg& operator=(const SafeEmitterArg&) = delete;
1041 
1042 /**
1043  * The destructor does not throw provided that the destructors of any
1044  * bound arguments do not throw (as they should not do), and assuming
1045  * that merely iterating through a list does not throw (as it would
1046  * not on any sane implementation). It is thread-safe as regards the
1047  * dropping of any connected functors and of any relevant Releaser
1048  * objects.
1049  */
1050  ~SafeEmitterArg();
1051 
1052 /* Only has effect if --with-glib-memory-slices-compat or
1053  * --with-glib-memory-slices-no-compat option picked */
1055 };
1056 
1057 template <class... FreeArgs>
1059 
1060  // go through emission_list() item by item, popping off the front and erasing
1061  // as we go in case Releaser::try_remove() fails to acquire the lock on one
1062  // of the iterations
1063  Thread::Mutex::Lock lock{mutex};
1064  while (!emission_list.empty()) {
1065  auto iter = emission_list.begin();
1066  int result = 0; // f2 might be a no-op
1067  // remove ourselves from the remote Releaser object
1068  (iter->f2)(&result);
1069  if (!result) { // we got the Releaser mutex lock or no-op
1070  // now remove this item from emission_list
1071  emission_list.erase(iter);
1072  }
1073  else {
1074  mutex.unlock();
1075  // spin nicely
1076 #ifdef CGU_USE_SCHED_YIELD
1077  sched_yield();
1078 #else
1079  usleep(10);
1080 #endif
1081  mutex.lock();
1082  }
1083  }
1084 }
1085 
1086 template <class... FreeArgs>
1088 
1089  // create a local copy of emission_list, to enable a connected
1090  // function (i) to delete the EmitterArg<> object to which it is
1091  // connected, even if there are other functors still to execute in
1092  // the same emission (which will execute normally provided they do
1093  // not try to call any of the emitter's functions), (ii) to call
1094  // 'delete this' nothwithstanding that the connected function is
1095  // protected by a Releaser object (assuming all the other restraints
1096  // on calling 'delete this' are met), provided that no other access
1097  // would be made to the deleted object in a function call connected
1098  // to the same emitter which is due to execute subsequently in the
1099  // same emission, and (iii) to disconnect itself from the
1100  // EmitterArg<> object. This design approach has a trade-off: if a
1101  // connected function tries to block, unblock or disconnect another
1102  // function connected to the same EmitterArg<> object which is due
1103  // to execute subsequently in the same emission (or to block,
1104  // unblock or disconnect itself when it is due to execute again
1105  // subsequently in the same emission), the attempted block, unblock
1106  // or disconnection will not have any effect on that emission (it
1107  // will only have effect on a subsequent emission). In addition, a
1108  // connected function may not destroy an object whose non-static
1109  // method is connected to the same emitter and which would execute
1110  // subsequently in the same emission, even if that object is
1111  // protected by a Releaser object (the non-static method will
1112  // unsuccessfully attempt to execute notwithstanding the destruction
1113  // of the object it would be operating on).
1114 
1115  // SafeFunctorArg usage has the additional point that while an
1116  // emission is in course, another thread should not try to do any of
1117  // those things, or the same outcome will result. Another thread
1118  // should leave alone objects connected to a SafeEmitterArg<> object
1119  // from the time of operator()() or emit() beginning to the time of
1120  // it ending, and not try to interfere.
1121 
1122  // a side effect of having a local list is that, as required, we
1123  // will not be holding our mutex when executing the functors it
1124  // contains. It is OK having the functors in two different lists
1125  // which are potentially (when our mutex is released) in two
1126  // different threads, because the functors hold their
1127  // Callback::Callback objects by SharedLockPtr so their reference
1128  // count is protected (they are SafeFunctorArg<> functors).
1129 
1130  std::list<ListItem> local_list;
1131  { // scope block for mutex lock
1132  Thread::Mutex::Lock lock{mutex};
1133  local_list = emission_list;
1134  }
1135 
1136 /*
1137  gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
1138  captures which comprise variadic arguments, and neither support
1139  range-based for, so iterate by hand
1140 */
1141  typename std::list<ListItem>::const_iterator iter;
1142  for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
1143  if (!iter->blocked) iter->f1(args...);
1144  }
1145 }
1146 
1147 template <class... FreeArgs>
1149 
1150  std::list<ListItem> local_list;
1151  { // scope block for mutex lock
1152  Thread::Mutex::Lock lock{mutex};
1153  if (emission_list.empty()) return false;
1154  local_list = emission_list;
1155  }
1156 
1157 /*
1158  gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
1159  captures which comprise variadic arguments, and neither support
1160  range-based for, so iterate by hand
1161 */
1162  typename std::list<ListItem>::const_iterator iter;
1163  for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
1164  if (!iter->blocked) iter->f1(args...);
1165  }
1166  return true;
1167 }
1168 
1169 template <class... FreeArgs>
1171  Thread::Mutex::Lock lock{mutex};
1172  emission_list.push_back(ListItem{f1, Callback::SafeFunctorArg<int*>()});
1173  return f1;
1174 }
1175 
1176 template <class... FreeArgs>
1178  // In this method:
1179  // f1 is the functor we execute when we emit()
1180  // f2 is the functor we execute in our destructor if we are destroyed before the
1181  // remote object is
1182  // f3 is the functor the remote object executes in its Releaser if it is destroyed
1183  // before we are, or if Releaser::operator=() is called
1184 
1186  Callback::SafeFunctorArg<int*> f2{Callback::make_ref(r, &Releaser::try_remove, f3)};
1187  // we can't call Releaser::add() when holding our mutex or we will
1188  // get out of order locking, as Releaser's mutex is acquired in that
1189  // method, and we don't need to do so
1190  r.add(f3);
1191  Thread::Mutex::Lock lock{mutex};
1192  try {
1193  emission_list.push_back(ListItem{f1, f2});
1194  }
1195  catch (...) {
1196  mutex.unlock();
1197  r.remove(f3);
1198  mutex.lock();
1199  throw;
1200  }
1201  return f1;
1202 }
1203 
1204 template <class... FreeArgs>
1206  // in theory, we could have connected the same functor object more than
1207  // once, so cater for that as well as Releaser::try_remove() failing
1208  Thread::Mutex::Lock lock{mutex};
1209  auto iter = emission_list.begin();
1210  for(;;) {
1211  /*
1212  // gcc-4.4 doesn't support lambdas:
1213  iter = std::find_if(iter, emission_list.end(),
1214  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
1215  */
1216  // so use a local struct and std::bind:
1217  struct Pred {
1218  static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
1219  return (p.f1 == f);
1220  }
1221  };
1222  iter = std::find_if(iter, emission_list.end(),
1223  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
1224  if (iter != emission_list.end()) {
1225  int result = 0; // f2 might be a no-op
1226  // remove ourselves from the remote Releaser object
1227  (iter->f2)(&result);
1228  if (!result) { // we got the Releaser mutex lock or no-op
1229  // now remove this item from emission_list
1230  iter = emission_list.erase(iter);
1231  }
1232  else {
1233  mutex.unlock();
1234  // spin nicely
1235 #ifdef CGU_USE_SCHED_YIELD
1236  sched_yield();
1237 #else
1238  usleep(10);
1239 #endif
1240  mutex.lock();
1241  // start again at the beginning - we have released the mutex
1242  // so our iterator may have become invalid
1243  iter = emission_list.begin();
1244  }
1245  }
1246  else break;
1247  }
1248 }
1249 
1250 // tracking disconnect() is the same as disconnect(), except that we do not
1251 // execute f2 as the remote Releaser object will destroy its own functors
1252 // in that case
1253 template <class... FreeArgs>
1255  Thread::Mutex::Lock lock{mutex};
1256  auto iter = emission_list.begin();
1257  for (;;) {
1258  // gcc-4.4 doesn't support lambdas:
1259  /*
1260  iter = std::find_if(iter, emission_list.end(),
1261  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
1262  */
1263  // so use a local struct and std::bind:
1264  struct Pred {
1265  static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
1266  return (p.f1 == f);
1267  }
1268  };
1269  iter = std::find_if(iter, emission_list.end(),
1270  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
1271  if (iter != emission_list.end()) {
1272  // remove this item from emission_list
1273  iter = emission_list.erase(iter);
1274  }
1275  else break;
1276  }
1277 }
1278 
1279 template <class... FreeArgs>
1281  // in theory, we could have connected the same functor object
1282  // more than once, so cater for that
1283  Thread::Mutex::Lock lock{mutex};
1284  auto iter = emission_list.begin();
1285  for (;;) {
1286  // gcc-4.4 doesn't support lambdas:
1287  /*
1288  iter = std::find_if(iter, emission_list.end(),
1289  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
1290  */
1291  // so use a local struct and std::bind:
1292  struct Pred {
1293  static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
1294  return (p.f1 == f);
1295  }
1296  };
1297  iter = std::find_if(iter, emission_list.end(),
1298  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
1299  if (iter != emission_list.end()) {
1300  iter->blocked = true;
1301  ++iter;
1302  }
1303  else break;
1304  }
1305 }
1306 
1307 template <class... FreeArgs>
1309  // in theory, we could have connected the same functor object
1310  // more than once, so cater for that
1311  Thread::Mutex::Lock lock{mutex};
1312  auto iter = emission_list.begin();
1313  for (;;) {
1314  // gcc-4.4 doesn't support lambdas:
1315  /*
1316  iter = std::find_if(iter, emission_list.end(),
1317  [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
1318  */
1319  // so use a local struct and std::bind:
1320  struct Pred {
1321  static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
1322  return (p.f1 == f);
1323  }
1324  };
1325  iter = std::find_if(iter, emission_list.end(),
1326  std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
1327  if (iter != emission_list.end()) {
1328  iter->blocked = false;
1329  ++iter;
1330  }
1331  else break;
1332  }
1333 }
1334 
1335 } // namespace Cgu
1336 
1337 #endif // EMITTER_H