c++-gtk-utils
emitter.h
Go to the documentation of this file.
00001 /* Copyright (C) 2009 to 2011 Chris Vine
00002 
00003 The library comprised in this file or of which this file is part is
00004 distributed by Chris Vine under the GNU Lesser General Public
00005 License as follows:
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public License
00009    as published by the Free Software Foundation; either version 2.1 of
00010    the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful, but
00013    WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License, version 2.1, for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License, version 2.1, along with this library (see the file LGPL.TXT
00019    which came with this source code package in the c++-gtk-utils
00020    sub-directory); if not, write to the Free Software Foundation, Inc.,
00021    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00022 
00023 However, it is not intended that the object code of a program whose
00024 source code instantiates a template from this file or uses macros or
00025 inline functions (of any length) should by reason only of that
00026 instantiation or use be subject to the restrictions of use in the GNU
00027 Lesser General Public License.  With that in mind, the words "and
00028 macros, inline functions and instantiations of templates (of any
00029 length)" shall be treated as substituted for the words "and small
00030 macros and small inline functions (ten lines or less in length)" in
00031 the fourth paragraph of section 5 of that licence.  This does not
00032 affect any other reason why object code may be subject to the
00033 restrictions in that licence (nor for the avoidance of doubt does it
00034 affect the application of section 2 of that licence to modifications
00035 of the source code in this file).
00036 
00037 */
00038 
00039 #ifndef CGU_EMITTER_H
00040 #define CGU_EMITTER_H
00041 
00042 /**
00043  * @file emitter.h
00044  * @brief This file provides a thread-safe signal/slot mechanism, with
00045  * automatic disconnection.
00046  *
00047  * An EmitterArg object is a list of Callback::FunctorArg objects.
00048  * Callback::FunctorArg objects may be "connected" to the EmitterArg
00049  * object, and all functors so connected will be executed when the
00050  * operator()() or emit() member functions of the EmitterArg object
00051  * concerned is called.  They will be called in the order in which
00052  * they were connected.  Emitter is a typedef for EmitterArg<>.  The
00053  * generalised EmitterArg<T...> type contains
00054  * Callback::FunctorArg<T...> objects (type T being the unbound
00055  * arguments of a Callback::CallbackArg<T...> callback - see
00056  * Cgu::Callback for further details, and "Usage" below for examples.)
00057  * The Emitter type holds Callback::Functor (namely
00058  * Callback::FunctorArg<>) objects.
00059  *
00060  * The main advantage of an emitter object as opposed to storing a
00061  * functor object directly, apart from the fact that more than one
00062  * functor can be dispatched by a single call to EmitterArg::emit() or
00063  * EmitterArg::operator()(), is that it provides for automatic
00064  * disconnection of a functor if the object whose member function it
00065  * represents has ceased to exist.
00066  *
00067  * Where automatic disconnection is wanted, the object whose method is
00068  * to be encapsulated by a functor must have a Releaser object as a
00069  * public member function.  The Releaser object should be passed as
00070  * the second argument of EmitterArg::connect().  As well as a
00071  * Releaser object informing an emitter object when it has ceased to
00072  * exist, an emitter object will do the same to the Releaser object if
00073  * the emitter object happens to be destroyed before an object whose
00074  * members it references (and therefore before the Releaser object).
00075  * Automatic disconnection is mainly useful for non-static member
00076  * functions, but it can be employed for static member functions or
00077  * non-member functions if wanted (that will in effect bind the
00078  * lifetime of the functor to that of the object to whose Releaser the
00079  * functor has been attached.)
00080  *
00081  * It is safe for a connected function (i) to delete the EmitterArg
00082  * object to which it is connected, even if there are other functors
00083  * still to execute in the same emission (which will execute normally
00084  * provided they do not try to call any of the emitter's functions),
00085  * (ii) to call 'delete this' nothwithstanding that the connected
00086  * function is protected by a Releaser object (assuming all the other
00087  * restraints on calling 'delete this' are met), provided that no
00088  * other access would be made to the deleted object in a function call
00089  * connected to the same emitter which is due to execute subsequently
00090  * in the same emission, and (iii) to disconnect itself from the
00091  * EmitterArg object.  This design approach has a trade-off: if a
00092  * connected function tries to block, unblock or disconnect another
00093  * function connected to the same EmitterArg object which is due to
00094  * execute subsequently in the same emission (or to block, unblock or
00095  * disconnect itself when it is due to execute again subsequently in
00096  * the same emission), the attempted block, unblock or disconnection
00097  * will not have any effect on that emission (it will only have effect
00098  * on a subsequent emission).  In addition, a connected function may
00099  * not destroy an object whose non-static method is connected to the
00100  * same emitter and which would execute subsequently in the same
00101  * emission, even if that object is protected by a Releaser object
00102  * (the non-static method will unsuccessfully attempt to execute
00103  * notwithstanding the destruction of the object it would be operating
00104  * on).
00105  *
00106  * The SafeEmitterArg classes are the same as their EmitterArg
00107  * counterparts except that they contain Callback::SafeFunctorArg
00108  * objects, and their emit(), operator()(), connect(), disconnect(),
00109  * block(), unblock() and destructor methods are protected by a mutex
00110  * so that different threads can call these methods on the same
00111  * emitter object, or create and delete the object.
00112  *
00113  * Note that the mutexes are released when the operator()()/emit()
00114  * methods of the relevent Callback::SafeFunctorArg objects are
00115  * called, as SafeEmitterArg objects have no idea what the referenced
00116  * callbacks will do so if they were not released deadlocks could
00117  * arise from recursive or out-of-order locking of the SafeEmitterArg
00118  * mutex.  It is therefore for users to provide additional
00119  * synchronisation if the functions encapsulated by the relevant
00120  * functors themselves need additional protection.  Note also the
00121  * subsidiary thread-safety points mentioned below.
00122  *
00123  * The Releaser class is intrinsically thread safe (the overhead of
00124  * locking is so low that it is pointless having a separate
00125  * unprotected class).  This means that if a program is
00126  * multi-threaded, you can use the plain EmitterArg classes provided
00127  * that only the thread which creates a particular EmitterArg object
00128  * calls connect(), block(), unblock((), emit() or operator()() on it,
00129  * or deletes it, or calls disconnect() on it (either directly or
00130  * through a Releaser object being destroyed).  Where more than one
00131  * thread might do that in relation to any one emitter object, use
00132  * SafeEmitterArg.
00133  *
00134  * @b Alternatives
00135  *
00136  * These classes are intended as a lightweight thread-safe signal/slot
00137  * mechanism for GUI programming.  For more demanding usage libsigc++
00138  * is a good choice, except that it is not thread-safe.  An
00139  * alternative to libsigc++ is the boost::signal2 module, which is
00140  * thread-safe.
00141  *
00142  * @b Subsidiary @b thread-safety @b points
00143  *
00144  * As mentioned, the SafeEmitterArg classes are thread safe, and their
00145  * methods can be called in different threads without ill effect.
00146  * However, there are some things that cannot be done.  Users should
00147  * observe two points.
00148  *
00149  * First, it has been mentioned that if a connected function blocks,
00150  * unblocks or disconnects another function connected to the same
00151  * emitter object and due to execute subsequently in the same
00152  * emission, the blocking, unblocking or disconnection will not have
00153  * effect in that emission, and that a connected function may not
00154  * delete an object whose non-static method is due to execute
00155  * subsequently in the same emission.  The same outcome would result
00156  * if another thread tries to do any of these things while an emission
00157  * is under way.  Another thread should therefore leave alone objects
00158  * connected to a SafeEmitterArg object from the time of operator()()
00159  * or emit() beginning to the time of it ending, and not try to
00160  * interfere.
00161  *
00162  * Secondly, when a Releaser object is passed as the second argument
00163  * to the connect() method of a SafeEmitterArg object, the Releaser
00164  * object must remain in existence until the connect() method returns
00165  * or the emitter may be left in an inconsistent state.
00166  *
00167  * @anchor AssignmentAnchor
00168  * @b Assignment
00169  *
00170  * EmitterArg and SafeEmitterArg objects cannot be copied.  Releaser
00171  * objects can be (we do not want to make a class uncopiable just
00172  * because it has the safety feature of having a Releaser object as a
00173  * member).
00174  *
00175  * So how should assignment of a Releaser object and of a class which
00176  * has a Releaser as a member be handled?  An object which has a
00177  * Releaser as a member and which is being assigned to (the assignee)
00178  * could keep all its existing pre-assignment emitter connections - so
00179  * far as the Releaser object is concerned, it will have to do so
00180  * where the connections are not protected by the Releaser object, and
00181  * we could do the same in relation to protected connections, in which
00182  * case we would make operator=() of Releaser do nothing: that is,
00183  * just return - a default assignment would always be wrong as it
00184  * would take the assignor's Releaser state but inherit none of its
00185  * connections, which the assignee cannot inherit as they depend on a
00186  * remote emitter object or objects.
00187  *
00188  * However, the state of the assignee after assignment may not be such
00189  * as to permit the inheriting of all the assignor's state except its
00190  * connections.  Accordingly, the default strategy adopted here is for
00191  * the Releaser object to become a blank sheet on assignment.  After
00192  * assignment, an assignee which has a Releaser object as a member
00193  * will no longer have any of the emitter connections which were,
00194  * prior to assignment, protected by the Releaser object.  If in a
00195  * particular case the user does not want this behaviour, she should
00196  * provide an assignment operator in the class which has Releaser as a
00197  * member and leave Releaser alone in the assignment operator.
00198  *
00199  * @b Usage
00200  *
00201  * For an object my_obj of class type MyClass, with a method void
00202  * MyClass::my_method(int, int, const char*), usage for a fully bound
00203  * functor and emitter would be:
00204  *
00205  * @code
00206  *   using namespace Cgu;
00207  *   int arg1 = 1, arg2 = 5;
00208  *   Emitter e;
00209  *   e.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
00210  *   e();
00211  *
00212  *   SafeEmitter se;
00213  *   se.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
00214  *   se();
00215  * @endcode
00216  *
00217  * Or for a partially bound functor and emitter:
00218  *
00219  * @code
00220  *   using namespace Cgu;
00221  *   int arg1 = 1, arg2 = 5;
00222  *   EmitterArg<int, const char*> e;
00223  *   e.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
00224  *   e(arg2, "Hello\n");
00225  *
00226  *   SafeEmitterArg<int, const char*> se;
00227  *   se.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
00228  *   se(arg2, "Hello\n");
00229  * @endcode
00230  *
00231  * EmitterArg classes do not provide for a return value.  If a
00232  * result is wanted, users should pass an unbound argument by
00233  * reference or pointer (or pointer to pointer).
00234  *
00235  * CallbackArg (and so FunctorArg and EmitterArg) objects can be
00236  * constructed for up to three bound arguments and an unlimited number
00237  * of unbound arguments, or from std::function objects (in which case
00238  * there is no limit to the number of bound arguments nor their
00239  * ordering with unbound arguments).  See Cgu::Callback for further
00240  * details.
00241  *
00242  * @b Exception @b safety
00243  *
00244  * Apart from the emit()/operator()() and connect() methods, nothing
00245  * done to an EmitterArg/SafeEmitterArg object should cause an
00246  * exception to be thrown.  This is because other methods only iterate
00247  * through a std::list object using std::for_each(), std::find() or by
00248  * hand, and the only things done by std::for_each() or after a
00249  * std::find() or iteration is to remove a functor from the list
00250  * (copying a functor and comparing functors never throw, nor does
00251  * destroying a functor provided the destructors of any bound argument
00252  * type do not throw).  Thus, an EmitterArg/SafeEmitterArg and
00253  * Releaser object should never get into an inconsistent state.
00254  *
00255  * The connect() method could throw a std::bad_alloc exception, either
00256  * on creating new functors or on pushing the functors onto the list.
00257  * However, were it to do so, the method has strong exception safety
00258  * (assuming merely iterating over a list does not throw, as it should
00259  * not).
00260  *
00261  * The emit()/operator()() methods could throw std::bad_alloc, and so
00262  * far as that is concerned emission of all the connected functions
00263  * will either all succeed or all fail.  In addition, the connected
00264  * functions referenced by the functors held by the emitter might
00265  * throw when executed.  emit()/operator()() do not attempt to catch
00266  * these exceptions as there is nothing they could do with them.  This
00267  * means that although a throwing connected function will not leave
00268  * the EmitterArg/SafeEmitterArg object in an inconsistent state, any
00269  * other connected functions due to execute subsequently on that same
00270  * emission will not execute.  If that is important in any particular
00271  * case, the user must incorporate logic in the connected functions to
00272  * cater for an exception causing only part execution, or must connect
00273  * only one function to any one signal and "chain" emissions by hand
00274  * so as to do the right thing.
00275  */
00276 
00277 /*
00278   Mutex locking heirarchy:
00279 
00280   Some out-of-order locking must take place because of the
00281   relationship between the Releaser and SafeEmitterArg<> classes.  The
00282   mutex of Releaser is given the higher priority.  This means that a
00283   plain EmitterArg<> object will not take any hit from the fact that
00284   Releaser is also useable with SafeEmitterArg<> objects.
00285 
00286   One consequence is that to avoid deadlocks, it is the
00287   SafeEmitterArg<> functions which must yield when a deadlock would
00288   otherwise arise.  Yielding could occur in
00289   SafeEmitterArg<>::~SafeEmitterArg() and
00290   SafeEmitterArg<>::disconnect().
00291 */
00292 
00293 #ifdef CGU_USE_SCHED_YIELD
00294 #include <sched.h>
00295 #else
00296 #include <unistd.h>
00297 #endif
00298 
00299 #include <list>
00300 #include <unordered_set>
00301 #include <algorithm>
00302 #include <functional>
00303 
00304 #include <c++-gtk-utils/callback.h>
00305 #include <c++-gtk-utils/mutex.h>
00306 #include <c++-gtk-utils/cgu_config.h>
00307 
00308 namespace Cgu {
00309 
00310 /* The four basic emitter types */
00311 
00312 template <class... FreeArgs> class EmitterArg;
00313 template <class... FreeArgs> class SafeEmitterArg;
00314 typedef EmitterArg<> Emitter;
00315 typedef SafeEmitterArg<> SafeEmitter;
00316 
00317 /** 
00318  * @class Releaser emitter.h c++-gtk-utils/emitter.h
00319  * @brief A class used for tracking EmitterArg and SafeEmitterArg
00320  * connections.
00321  * @sa EmitterArg SafeEmitterArg
00322  * @sa emitter.h
00323  * @sa Callback namespace
00324  *
00325  * This class provides tracking of EmitterArg and SafeEmitterArg
00326  * connections.  It should be a public member of any target class
00327  * which wants functors representing any of its methods to be
00328  * disconnected automatically from an EmitterArg or SafeEmitterArg
00329  * object when the target class object is destroyed, and is passed as
00330  * one of the arguments to the connect() method of EmitterArg or
00331  * SafeEmitterArg.
00332  *
00333  * All its methods are thread-safe.
00334  * 
00335  * For further background, read this: emitter.h
00336  */
00337 
00338 class Releaser {
00339 
00340   // from version 2.0.0-rc3 we use std::unordered_set rather than
00341   // std::list in Releaser.  We can't do that for
00342   // EmitterArg/SafeEmitterArg objects, as they need to execute
00343   // connected functors in the order in which they were connected.
00344   std::unordered_set<Callback::SafeFunctor> disconnect_set;
00345   Thread::Mutex mutex;
00346 
00347   // only an EmitterArg or SafeEmitterArg object can access add(), remove and try_remove()
00348   void add(const Callback::SafeFunctor&);
00349   void remove(const Callback::SafeFunctor&);
00350   void try_remove(const Callback::SafeFunctor&, int*);
00351 public:
00352   template <class... T> friend class EmitterArg;
00353   template <class... T> friend class SafeEmitterArg;
00354 
00355   // operator=() and the copy constructor should copy nothing from the
00356   // assignor, because disconnect_set should be empty in the
00357   // assignee, as any class containing us does not acquire as assignee
00358   // any emitter functors representing any of its methods
00359 
00360 /**
00361  * See notes on @ref AssignmentAnchor "assignment" to see how this
00362  * operates.  This does not throw provided that the destructors of any
00363  * bound arguments of a functor managed by this Releaser object prior
00364  * to assignment do not throw (as they should not do), and assuming
00365  * that merely iterating through a list does not throw (as it would
00366  * not on any sane implementation).
00367  * @param r The assignee.
00368  */
00369   Releaser& operator=(const Releaser& r);
00370 
00371 /**
00372  * This does not copy anything from the Releaser object passed as an
00373  * argument - see the notes on @ref AssignmentAnchor "assignment" for
00374  * an explanation of why.  This does not throw.
00375  * @param r A Releaser object.
00376  * @exception std::bad_alloc This constructor might throw
00377  * std::bad_alloc if memory is exhausted and the system throws in that
00378  * case.
00379  * @exception Thread::MutexError This constructor might throw
00380  * Thread::MutexError if initialisation of the contained mutex fails.
00381  * (It is often not worth checking for this, as it means either memory
00382  * is exhausted or pthread has run out of other resources to create
00383  * new mutexes.)
00384  */
00385   Releaser(const Releaser& r) {}
00386 
00387 /**
00388  * @exception std::bad_alloc The default constructor might throw
00389  * std::bad_alloc if memory is exhausted and the system throws in that
00390  * case.
00391  * @exception Thread::MutexError The default constructor might throw
00392  * Thread::MutexError if initialisation of the contained mutex fails.
00393  * (It is often not worth checking for this, as it means either memory
00394  * is exhausted or pthread has run out of other resources to create
00395  * new mutexes.)
00396  */
00397   Releaser() = default;
00398 
00399 /**
00400  * The destructor does not throw provided that the destructors of any
00401  * bound arguments of a functor managed by this Releaser object do not
00402  * throw (as they should not do), and assuming that merely iterating
00403  * through an unordered_set does not throw (as it would not on any
00404  * sane implementation).
00405  */
00406   ~Releaser();
00407 
00408 /* Only has effect if --with-glib-memory-slices-compat or
00409  * --with-glib-memory-slices-no-compat option picked */
00410   CGU_GLIB_MEMORY_SLICES_FUNCS
00411 };
00412 
00413 /* the emitter classes */
00414 
00415 /**
00416  * @class EmitterArg emitter.h c++-gtk-utils/emitter.h
00417  * @brief A class to execute callbacks connected to it, with provision
00418  * for automatic disconnection.
00419  * @sa SafeEmitterArg Releaser
00420  * @sa emitter.h
00421  * @sa Callback namespace
00422  *
00423  * Callback::FunctorArg objects may be connected to Emitter classes,
00424  * and will be executed when EmitterArg::emit() or
00425  * EmitterArg::operator()() are called.
00426  *
00427  * One version of the connect() method takes a Releaser object as an
00428  * argument.  Such a Releaser object should be a public member of any
00429  * target class which wants functors representing any of its methods
00430  * to be disconnected automatically from the EmitterArg object when
00431  * the target class object is destroyed.
00432  *
00433  * A connection may be explicitly disconnected by calling the
00434  * disconnect() method, and may also be temporarily blocked and
00435  * subsequently unblocked with the block() and unblock() methods.
00436  *
00437  * The template type is the type of the unbound argument, if any.
00438  * EmitterArg<> is typedef'ed to Emitter.
00439  *
00440  * @b Usage
00441  *
00442  * For a class my_obj of type MyClass, with a method void
00443  * MyClass::my_method(int, int, const char*), usage for a fully bound functor
00444  * and emitter would be:
00445  *
00446  * @code
00447  *   using namespace Cgu;
00448  *   int arg1 = 1, arg2 = 5;
00449  *   Emitter e;
00450  *   e.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
00451  *   e();
00452  * @endcode
00453  *
00454  * Or for a partially bound functor and emitter:
00455  *
00456  * @code
00457  *   using namespace Cgu;
00458  *   int arg1 = 1, arg2 = 5;
00459  *   EmitterArg<int, const char*> e;
00460  *   e.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
00461  *   e(arg2, "Hello\n");
00462  * @endcode
00463  * 
00464  * For further background, including about thread-safety and exception
00465  * safety and other matters, read this: emitter.h, or for more
00466  * information about bound and unbound arguments, read this:
00467  * Cgu::Callback.
00468  */
00469 
00470 template <class... FreeArgs>
00471 class EmitterArg {
00472 
00473 #ifndef DOXYGEN_PARSING
00474   // f1 is the functor we execute when we emit()
00475   // f2 is the functor we execute in our destructor if we are destroyed
00476   // before the remote object is
00477   struct ListItem {
00478     Callback::FunctorArg<FreeArgs...> f1;
00479     Callback::Functor f2;
00480     bool blocked;
00481     ListItem(Callback::FunctorArg<FreeArgs...> f1_, Callback::Functor f2_):
00482       f1(f1_), f2(f2_), blocked(false) {}
00483   };
00484 #endif
00485 
00486   std::list<ListItem> emission_list;
00487 
00488   // only Releaser objects can access this
00489   void tracking_disconnect(const Callback::FunctorArg<FreeArgs...>&);
00490 
00491 public:
00492   friend class Releaser;
00493 
00494 /**
00495  * This will execute the connected functors.
00496  * @param args The unbound arguments to be passed to the referenced
00497  * function or class method, if any.
00498  * @exception std::bad_alloc The method might throw std::bad_alloc if
00499  * memory is exhausted and the system throws in that case.  In
00500  * addition, it will throw if the functions or class methods
00501  * referenced by the functors throw (or if the copy constructor of a
00502  * free or bound argument throws and it is not a reference argument).
00503  */
00504   void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {emit(args...);}
00505 
00506 /**
00507  * This will execute the connected functors.
00508  * @param args The unbound arguments to be passed to the referenced
00509  * function or class method, if any.
00510  * @exception std::bad_alloc The method might throw std::bad_alloc if
00511  * memory is exhausted and the system throws in that case.  In
00512  * addition, it will throw if the functions or class methods
00513  * referenced by the functors throw (or if the copy constructor of a
00514  * free or bound argument throws and it is not a reference argument).
00515  */
00516   void emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
00517 
00518 /**
00519  * This will execute the connected functors, but it also reports
00520  * whether in fact there were any connected functors to execute.  (It
00521  * is not necessary to use this function just because it is not known
00522  * whether a functor is connected - if the standard emit() function is
00523  * called when no functor is connected, nothing will happen.  The
00524  * feature of this method is that it will report the outcome.)
00525  * @param args The unbound arguments to be passed to the connected
00526  * functions or class methods, if any.
00527  * @return Returns false if there were no functors to execute, or true
00528  * if functors have been executed.
00529  * @exception std::bad_alloc The method might throw std::bad_alloc if
00530  * memory is exhausted and the system throws in that case.  In
00531  * addition, it will throw if the functions or class methods
00532  * referenced by the functors throw (or if the copy constructor of a
00533  * free or bound argument throws and it is not a reference argument).
00534  */
00535   bool test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
00536 
00537 /**
00538  * Connects a functor.
00539  * @param f The functor to connect.
00540  * @return The functor connected.
00541  * @exception std::bad_alloc The method might throw std::bad_alloc if
00542  * memory is exhausted and the system throws in that case.
00543  */
00544   Callback::FunctorArg<FreeArgs...> connect(const Callback::FunctorArg<FreeArgs...>& f);
00545 
00546 /**
00547  * Connects a functor.
00548  * @param f The functor to connect.
00549  * @param r A Releaser object for automatic disconnection of the
00550  * functor if the object whose method it represents is destroyed.
00551  * @return The functor connected.
00552  * @exception std::bad_alloc The method might throw std::bad_alloc if
00553  * memory is exhausted and the system throws in that case.
00554  */
00555   Callback::FunctorArg<FreeArgs...> connect(const Callback::FunctorArg<FreeArgs...>& f, Releaser& r);
00556 
00557 /**
00558  * Disconnects a functor previously connected. This does not throw
00559  * provided that the destructors of any bound arguments do not throw
00560  * (as they should not do), and assuming that merely iterating through
00561  * a list does not throw (as it would not on any sane implementation).
00562  * @param f The functor to disconnect.
00563  * @note If the same functor has been connected more than once to the
00564  * same EmitterArg object, this call will disconnect all of them.
00565  */
00566   void disconnect(const Callback::FunctorArg<FreeArgs...>& f);
00567 
00568 /**
00569  * Blocks a connected functor from executing when emit() or
00570  * operator()() is called until unblock() is called.  This method does
00571  * not throw (assuming that merely iterating through a list does not
00572  * throw, as it would not on any sane implementation).
00573  * @param f The functor to block.
00574  * @note If the same functor has been connected more than once to the
00575  * same EmitterArg object, this call will block all of them.
00576  */
00577   void block(const Callback::FunctorArg<FreeArgs...>& f);
00578 
00579 /**
00580  * Unblocks a previously blocked functor.  This method does not throw
00581  * (assuming that merely iterating through a list does not throw, as
00582  * it would not on any sane implementation).
00583  * @param f The functor to unblock.
00584  * @note If the same functor has been connected more than once to the
00585  * same EmitterArg object, this call will unblock all of them.
00586  */
00587   void unblock(const Callback::FunctorArg<FreeArgs...>& f);
00588 
00589 /**
00590  * @exception std::bad_alloc The constructor might throw
00591  * std::bad_alloc if memory is exhausted and the system throws in that
00592  * case.
00593  */
00594   EmitterArg() = default;
00595 
00596 /**
00597  * This class cannot be copied.  The copy constructor is deleted.
00598  */
00599   EmitterArg(const EmitterArg&) = delete;
00600 
00601 /**
00602  * This class cannot be copied.  The assignment operator is deleted.
00603  */
00604   EmitterArg& operator=(const EmitterArg&) = delete;
00605 
00606 /**
00607  * The destructor does not throw provided that the destructors of any
00608  * bound arguments do not throw (as they should not do), and assuming
00609  * that merely iterating through a list does not throw (as it would
00610  * not on any sane implementation).
00611  */
00612   ~EmitterArg();
00613 
00614 /* Only has effect if --with-glib-memory-slices-compat or
00615  * --with-glib-memory-slices-no-compat option picked */
00616   CGU_GLIB_MEMORY_SLICES_FUNCS
00617 };
00618 
00619 template <class... FreeArgs>
00620 EmitterArg<FreeArgs...>::~EmitterArg() {
00621 
00622   // gcc-4.4 and 4.5 don't support this:
00623   /*
00624   for(const ListItem& l: emission_list) {l.f2();}
00625   */
00626   // gcc-4.4 doesn't support this;
00627   /*
00628   std::for_each(emission_list.begin(), emission_list.end(),
00629                 [](const ListItem& l){(l.f2)();});
00630   */
00631   // So do it the old way:
00632   struct DisconnectReleaserItem {
00633     static void exec(const ListItem& l) {(l.f2)();}
00634   };
00635   std::for_each(emission_list.begin(), emission_list.end(),
00636                 DisconnectReleaserItem::exec);
00637 }
00638 
00639 template <class... FreeArgs>
00640 void EmitterArg<FreeArgs...>::emit(typename Cgu::Param<FreeArgs>::ParamType... args) const {
00641 
00642   // create a local copy of emission_list, to enable a connected
00643   // function (i) to delete the EmitterArg<> object to which it is
00644   // connected, even if there are other functors still to execute in
00645   // the same emission (which will execute normally provided they do
00646   // not try to call any of the emitter's functions), (ii) to call
00647   // 'delete this' nothwithstanding that the connected function is
00648   // protected by a Releaser object (assuming all the other restraints
00649   // on calling 'delete this' are met), provided that no other access
00650   // would be made to the deleted object in a function call connected
00651   // to the same emitter which is due to execute subsequently in the
00652   // same emission, and (iii) to disconnect itself from the
00653   // EmitterArg object.  This design approach has a trade-off: if a
00654   // connected function tries to block, unblock or disconnect another
00655   // function connected to the same EmitterArg<> object which is due
00656   // to execute subsequently in the same emission (or to block,
00657   // unblock or disconnect itself when it is due to execute again
00658   // subsequently in the same emission), the attempted block, unblock
00659   // or disconnection will not have any effect on that emission (it
00660   // will only have effect on a subsequent emission).  In addition, a
00661   // connected function may not destroy an object whose non-static
00662   // method is connected to the same emitter and which would execute
00663   // subsequently in the same emission, even if that object is
00664   // protected by a Releaser object (the non-static method will
00665   // unsuccessfully attempt to execute notwithstanding the destruction
00666   // of the object it would be operating on).
00667 
00668   // we can't use uniform initialisation here as it would be
00669   // construed as invoking an initialiser list with a list item,
00670   // rather than passing an already formed list
00671   std::list<ListItem> local_list = emission_list;
00672 
00673 /*
00674   gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
00675   captures which comprise variadic arguments, and neither support
00676   range-based for, so iterate by hand
00677 */
00678   typename std::list<ListItem>::const_iterator iter;
00679   for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
00680     if (!iter->blocked) iter->f1(args...);
00681   }
00682 }
00683 
00684 template <class... FreeArgs>
00685 bool EmitterArg<FreeArgs...>::test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const {
00686   if (emission_list.empty()) return false;
00687   emit(args...);
00688   return true;
00689 }
00690 
00691 template <class... FreeArgs>
00692 Callback::FunctorArg<FreeArgs...> EmitterArg<FreeArgs...>::connect(const Callback::FunctorArg<FreeArgs...>& f1) {
00693   emission_list.push_back(ListItem{f1, Callback::Functor()});
00694   return f1;
00695 }
00696 
00697 template <class... FreeArgs>
00698 Callback::FunctorArg<FreeArgs...> EmitterArg<FreeArgs...>::connect(const Callback::FunctorArg<FreeArgs...>& f1, Releaser& r) {
00699   // In this method:
00700   // f1 is the functor we execute when we emit()
00701   // f2 is the functor we execute in our destructor if we are destroyed before the
00702   // remote object is
00703   // f3 is the functor the remote object executes in its Releaser if it is destroyed
00704   // before we are, or if Releaser::operator=() is called
00705 
00706   Callback::SafeFunctor f3{Callback::make_ref(*this, &EmitterArg<FreeArgs...>::tracking_disconnect, f1)};
00707   Callback::Functor f2{Callback::make_ref(r, &Releaser::remove, f3)};
00708   r.add(f3);
00709   try {
00710     emission_list.push_back(ListItem{f1, f2});
00711   }
00712   catch (...) {
00713     r.remove(f3);
00714     throw;
00715   }
00716   return f1;
00717 }
00718 
00719 template <class... FreeArgs>
00720 void EmitterArg<FreeArgs...>::disconnect(const Callback::FunctorArg<FreeArgs...>& arg) {
00721   // in theory, we could have connected the same functor object
00722   // more than once, so cater for that
00723   auto iter = emission_list.begin();
00724   for (;;) {
00725     // gcc-4.4 doesn't support lambdas:
00726     /*
00727     iter = std::find_if(iter, emission_list.end(),
00728                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
00729     */
00730     // so use a local struct and std::bind:
00731     struct Pred {
00732       static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
00733         return (p.f1 == f);
00734       }
00735     };
00736     iter = std::find_if(iter, emission_list.end(),
00737                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
00738     if (iter != emission_list.end()) {
00739       // remove ourselves from the remote Releaser object
00740       (iter->f2)();
00741 
00742       // remove this item from emission_list
00743       iter = emission_list.erase(iter);
00744     }
00745     else break;
00746   }
00747 }
00748 
00749 // tracking disconnect() is the same as disconnect(), except that we do not
00750 // execute f2 as the remote Releaser object will destroy its own functors
00751 // in that case
00752 template <class... FreeArgs>
00753 void EmitterArg<FreeArgs...>::tracking_disconnect(const Callback::FunctorArg<FreeArgs...>& arg) {
00754   auto iter = emission_list.begin();
00755   for (;;) {
00756     // gcc-4.4 doesn't support lambdas:
00757     /*
00758     iter = std::find_if(iter, emission_list.end(),
00759                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
00760     */
00761     // so use a local struct and std::bind:
00762     struct Pred {
00763       static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
00764         return (p.f1 == f);
00765       }
00766     };
00767     iter = std::find_if(iter, emission_list.end(),
00768                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
00769     if (iter != emission_list.end()) {
00770       // remove this item from emission_list
00771       iter = emission_list.erase(iter);
00772     }
00773     else break;
00774   }
00775 }
00776 
00777 template <class... FreeArgs>
00778 void EmitterArg<FreeArgs...>::block(const Callback::FunctorArg<FreeArgs...>& arg) {
00779   // in theory, we could have connected the same functor object
00780   // more than once, so cater for that
00781   auto iter = emission_list.begin();
00782   for (;;) {
00783     // gcc-4.4 doesn't support lambdas:
00784     /*
00785     iter = std::find_if(iter, emission_list.end(),
00786                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
00787     */
00788     // so use a local struct and std::bind:
00789     struct Pred {
00790       static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
00791         return (p.f1 == f);
00792       }
00793     };
00794     iter = std::find_if(iter, emission_list.end(),
00795                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
00796     if (iter != emission_list.end()) {
00797       iter->blocked = true;
00798       ++iter;
00799     }
00800     else break;
00801   }
00802 }
00803 
00804 template <class... FreeArgs>
00805 void EmitterArg<FreeArgs...>::unblock(const Callback::FunctorArg<FreeArgs...>& arg) {
00806   // in theory, we could have connected the same functor object
00807   // more than once, so cater for that
00808   auto iter = emission_list.begin();
00809   for (;;) {
00810     // gcc-4.4 doesn't support lambdas:
00811     /*
00812     iter = std::find_if(iter, emission_list.end(),
00813                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
00814     */
00815     // so use a local struct and std::bind:
00816     struct Pred {
00817       static bool pred(const ListItem& p, const Callback::FunctorArg<FreeArgs...>& f) {
00818         return (p.f1 == f);
00819       }
00820     };
00821     iter = std::find_if(iter, emission_list.end(),
00822                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
00823     if (iter != emission_list.end()) {
00824       iter->blocked = false;
00825       ++iter;
00826     }
00827     else break;
00828   }
00829 }
00830 
00831 /**
00832  * @class SafeEmitterArg emitter.h c++-gtk-utils/emitter.h
00833  * @brief A thread-safe class to execute callbacks connected to it,
00834  * with provision for automatic disconnection.
00835  * @sa EmitterArg Releaser
00836  * @sa emitter.h
00837  * @sa Callback namespace
00838  *
00839  * This is a thread-safe version of the EmitterArg class.
00840  * Callback::SafeFunctorArg objects may be connected to SafeEmitter
00841  * classes, and will be executed when SafeEmitterArg::emit() or
00842  * SafeEmitterArg::operator()() are called.
00843  *
00844  * One version of the connect() method takes a Releaser object as an
00845  * argument.  Such a Releaser object should be a public member of any
00846  * target class which wants functors representing any of its methods
00847  * to be disconnected automatically from the SafeEmitterArg object
00848  * when the target class object is destroyed.
00849  *
00850  * A connection may be explicitly disconnected by calling the
00851  * disconnect() method, and may also be temporarily blocked and
00852  * subsequently unblocked with the block() and unblock() methods.
00853  *
00854  * The template type is the type of the unbound argument, if any.
00855  * SafeEmitterArg<> is typedef'ed to SafeEmitter.
00856  *
00857  * @b Usage
00858  *
00859  * For a class my_obj of type MyClass, with a method void
00860  * MyClass::my_method(int, int, const char*), usage for a fully bound
00861  * functor and emitter would be:
00862  *
00863  * @code
00864  *   using namespace Cgu;
00865  *   int arg1 = 1, arg2 = 5;
00866  *   SafeEmitter se;
00867  *   se.connect(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
00868  *   se();
00869  * @endcode
00870  *
00871  * Or for a partially bound functor and emitter:
00872  *
00873  * @code
00874  *   using namespace Cgu;
00875  *   int arg1 = 1, arg2 = 5;
00876  *   SafeEmitterArg<int, const char*> se;
00877  *   se.connect(Callback::make(my_obj, &MyClass::my_method, arg1));
00878  *   se(arg2, "Hello\n");
00879  * @endcode
00880  * 
00881  * For further background, including about thread-safety and exception
00882  * safety and other matters, read this: emitter.h, or for more
00883  * information about bound and unbound arguments, read this:
00884  * Cgu::Callback.
00885  */
00886 
00887 template <class... FreeArgs>
00888 class SafeEmitterArg {
00889 
00890 #ifndef DOXYGEN_PARSING
00891   // f1 is the functor we execute when we emit()
00892   // f2 is the functor we execute in our destructor if we are destroyed
00893   // before the remote object is
00894   struct ListItem {
00895     Callback::SafeFunctorArg<FreeArgs...> f1;
00896     Callback::SafeFunctorArg<int*> f2;
00897     bool blocked;
00898     ListItem(Callback::SafeFunctorArg<FreeArgs...> f1_, Callback::SafeFunctorArg<int*> f2_):
00899       f1(f1_), f2(f2_), blocked(false) {}
00900   };
00901 #endif
00902   
00903   std::list<ListItem> emission_list;
00904   mutable Thread::Mutex mutex; // make this mutable so we can lock/unlock in const methods
00905 
00906   // only Releaser objects can access this
00907   void tracking_disconnect(const Callback::SafeFunctorArg<FreeArgs...>&);
00908 
00909 public:
00910   friend class Releaser;
00911 
00912 /**
00913  * This will execute the connected functors.  It is thread safe if the
00914  * functions or class methods referenced by the connected functors are
00915  * thread safe.
00916  * @param args The unbound arguments to be passed to the referenced
00917  * function or class method, if any.
00918  * @exception std::bad_alloc The method might throw std::bad_alloc if
00919  * memory is exhausted and the system throws in that case.  In
00920  * addition, it will throw if the functions or class methods
00921  * referenced by the functors throw (or if the copy constructor of a
00922  * free or bound argument throws and it is not a reference argument).
00923  */
00924   void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {emit(args...);}
00925 
00926 /**
00927  * This will execute the connected functors.  It is thread safe if the
00928  * functions or class methods referenced by the connected functors are
00929  * thread safe.
00930  * @param args The unbound arguments to be passed to the referenced
00931  * function or class method, if any.
00932  * @exception std::bad_alloc The method might throw std::bad_alloc if
00933  * memory is exhausted and the system throws in that case.  In
00934  * addition, it will throw if the functions or class methods
00935  * referenced by the functors throw (or if the copy constructor of a
00936  * free or bound argument throws and it is not a reference argument).
00937  */
00938   void emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
00939 
00940 /**
00941  * This will execute the connected functors, but it also reports
00942  * whether in fact there were any connected functors to execute.  It
00943  * is thread safe if the functions or class methods referenced by the
00944  * connected functors are thread safe.  (It is not necessary to use
00945  * this function just because it is not known whether a functor is
00946  * connected - if the standard emit() function is called when no
00947  * functor is connected, nothing will happen.  The feature of this
00948  * method is that it will report the outcome.)
00949  * @param args The unbound arguments to be passed to the referenced
00950  * function or class method, if any.
00951  * @return Returns false if there were no functors to execute, or true
00952  * if functors have been executed.
00953  * @exception std::bad_alloc The method might throw std::bad_alloc if
00954  * memory is exhausted and the system throws in that case.  In
00955  * addition, it will throw if the functions or class methods
00956  * referenced by the functors throw (or if the copy constructor of a
00957  * free or bound argument throws and it is not a reference argument).
00958  */
00959   bool test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const;
00960 
00961 /**
00962  * Connects a functor.  It is thread safe.
00963  * @param f The functor to connect.
00964  * @return The functor connected.
00965  * @exception std::bad_alloc The method might throw std::bad_alloc if
00966  * memory is exhausted and the system throws in that case.
00967  */
00968   Callback::SafeFunctorArg<FreeArgs...> connect(const Callback::SafeFunctorArg<FreeArgs...>& f);
00969 
00970 /**
00971  * Connects a functor.  It is thread safe.
00972  * @param f The functor to connect.
00973  * @param r A Releaser object for automatic disconnection of the
00974  * functor if the object whose method it represents is destroyed.
00975  * @return The functor connected.
00976  * @exception std::bad_alloc The method might throw std::bad_alloc if
00977  * memory is exhausted and the system throws in that case.
00978  */
00979   Callback::SafeFunctorArg<FreeArgs...> connect(const Callback::SafeFunctorArg<FreeArgs...>& f, Releaser& r);
00980 
00981 /**
00982  * Disconnects a functor previously connected. This does not throw
00983  * provided that the destructors of any bound arguments do not throw
00984  * (as they should not do), and assuming that merely iterating through
00985  * a list does not throw (as it would not on any sane implementation).
00986  * It is thread safe.
00987  * @param f The functor to disconnect.
00988  * @note If the same functor has been connected more than once to the
00989  * same SafeEmitterArg object, this call will disconnect all of them.
00990  */
00991   void disconnect(const Callback::SafeFunctorArg<FreeArgs...>& f);
00992 
00993 /**
00994  * Blocks a connected functor from executing when emit() or
00995  * operator()() is called until unblock() is called.  This method does
00996  * not throw (assuming that merely iterating through a list does not
00997  * throw, as it would not on any sane implementation).  It is thread
00998  * safe.
00999  * @param f The functor to block.
01000  * @note If the same functor has been connected more than once to the
01001  * same SafeEmitterArg object, this call will block all of them.
01002  */
01003   void block(const Callback::SafeFunctorArg<FreeArgs...>& f);
01004 
01005 /**
01006  * Unblocks a previously blocked functor.  This method does not throw
01007  * (assuming that merely iterating through a list does not throw, as
01008  * it would not on any sane implementation).  It is thread safe.
01009  * @param f The functor to unblock.
01010  * @note If the same functor has been connected more than once to the
01011  * same SafeEmitterArg object, this call will unblock all of them.
01012  */
01013   void unblock(const Callback::SafeFunctorArg<FreeArgs...>& f);
01014 
01015 /**
01016  * @exception std::bad_alloc The constructor might throw
01017  * std::bad_alloc if memory is exhausted and the system throws in that
01018  * case.
01019  * @exception Thread::MutexError The constructor might throw
01020  * Thread::MutexError if initialisation of the contained mutex fails.
01021  * (It is often not worth checking for this, as it means either memory
01022  * is exhausted or pthread has run out of other resources to create
01023  * new mutexes.)
01024  */
01025   SafeEmitterArg() = default;
01026 
01027 /**
01028  * This class cannot be copied.  The copy constructor is deleted.
01029  */
01030   SafeEmitterArg(const SafeEmitterArg&) = delete;
01031 
01032 /**
01033  * This class cannot be copied.  The assignment operator is deleted.
01034  */
01035   SafeEmitterArg& operator=(const SafeEmitterArg&) = delete;
01036 
01037 /**
01038  * The destructor does not throw provided that the destructors of any
01039  * bound arguments do not throw (as they should not do), and assuming
01040  * that merely iterating through a list does not throw (as it would
01041  * not on any sane implementation).  It is thread-safe as regards the
01042  * dropping of any connected functors and of any relevant Releaser
01043  * objects.
01044  */
01045   ~SafeEmitterArg();
01046 
01047 /* Only has effect if --with-glib-memory-slices-compat or
01048  * --with-glib-memory-slices-no-compat option picked */
01049   CGU_GLIB_MEMORY_SLICES_FUNCS
01050 };
01051 
01052 template <class... FreeArgs>
01053 SafeEmitterArg<FreeArgs...>::~SafeEmitterArg() {
01054 
01055   // go through emission_list() item by item, popping off the front and erasing
01056   // as we go in case Releaser::try_remove() fails to acquire the lock on one
01057   // of the iterations
01058   Thread::Mutex::Lock lock{mutex};
01059   while (!emission_list.empty()) {
01060     auto iter = emission_list.begin();
01061     int result = 0; // f2 might be a no-op
01062     // remove ourselves from the remote Releaser object
01063     (iter->f2)(&result);
01064     if (!result) { // we got the Releaser mutex lock or no-op
01065       // now remove this item from emission_list
01066       emission_list.erase(iter);
01067     }
01068     else {
01069       mutex.unlock();
01070       // spin nicely
01071 #ifdef CGU_USE_SCHED_YIELD
01072       sched_yield();
01073 #else
01074       usleep(10);
01075 #endif
01076       mutex.lock();
01077     }
01078   }
01079 }
01080 
01081 template <class... FreeArgs>
01082 void SafeEmitterArg<FreeArgs...>::emit(typename Cgu::Param<FreeArgs>::ParamType... args) const {
01083 
01084   // create a local copy of emission_list, to enable a connected
01085   // function (i) to delete the EmitterArg<> object to which it is
01086   // connected, even if there are other functors still to execute in
01087   // the same emission (which will execute normally provided they do
01088   // not try to call any of the emitter's functions), (ii) to call
01089   // 'delete this' nothwithstanding that the connected function is
01090   // protected by a Releaser object (assuming all the other restraints
01091   // on calling 'delete this' are met), provided that no other access
01092   // would be made to the deleted object in a function call connected
01093   // to the same emitter which is due to execute subsequently in the
01094   // same emission, and (iii) to disconnect itself from the
01095   // EmitterArg<> object.  This design approach has a trade-off: if a
01096   // connected function tries to block, unblock or disconnect another
01097   // function connected to the same EmitterArg<> object which is due
01098   // to execute subsequently in the same emission (or to block,
01099   // unblock or disconnect itself when it is due to execute again
01100   // subsequently in the same emission), the attempted block, unblock
01101   // or disconnection will not have any effect on that emission (it
01102   // will only have effect on a subsequent emission).  In addition, a
01103   // connected function may not destroy an object whose non-static
01104   // method is connected to the same emitter and which would execute
01105   // subsequently in the same emission, even if that object is
01106   // protected by a Releaser object (the non-static method will
01107   // unsuccessfully attempt to execute notwithstanding the destruction
01108   // of the object it would be operating on).
01109 
01110   // SafeFunctorArg usage has the additional point that while an
01111   // emission is in course, another thread should not try to do any of
01112   // those things, or the same outcome will result.  Another thread
01113   // should leave alone objects connected to a SafeEmitterArg<> object
01114   // from the time of operator()() or emit() beginning to the time of
01115   // it ending, and not try to interfere.
01116 
01117   // a side effect of having a local list is that, as required, we
01118   // will not be holding our mutex when executing the functors it
01119   // contains.  It is OK having the functors in two different lists
01120   // which are potentially (when our mutex is released) in two
01121   // different threads, because the functors hold their
01122   // Callback::Callback objects by SharedLockPtr so their reference
01123   // count is protected (they are SafeFunctorArg<> functors).
01124 
01125   std::list<ListItem> local_list;
01126   { // scope block for mutex lock
01127     Thread::Mutex::Lock lock{mutex};
01128     local_list = emission_list;
01129   }
01130 
01131 /*
01132   gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
01133   captures which comprise variadic arguments, and neither support
01134   range-based for, so iterate by hand
01135 */
01136   typename std::list<ListItem>::const_iterator iter;
01137   for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
01138     if (!iter->blocked) iter->f1(args...);
01139   }
01140 }
01141 
01142 template <class... FreeArgs>
01143 bool SafeEmitterArg<FreeArgs...>::test_emit(typename Cgu::Param<FreeArgs>::ParamType... args) const {
01144 
01145   std::list<ListItem> local_list;
01146   { // scope block for mutex lock
01147     Thread::Mutex::Lock lock{mutex};
01148     if (emission_list.empty()) return false;
01149     local_list = emission_list;
01150   }
01151 
01152 /*
01153   gcc-4.4 doesn't support lambdas, gcc-4.5 doesn't like lambda
01154   captures which comprise variadic arguments, and neither support
01155   range-based for, so iterate by hand
01156 */
01157   typename std::list<ListItem>::const_iterator iter;
01158   for (iter = local_list.begin(); iter != local_list.end(); ++iter) {
01159     if (!iter->blocked) iter->f1(args...);
01160   }
01161   return true;
01162 }
01163 
01164 template <class... FreeArgs>
01165 Callback::SafeFunctorArg<FreeArgs...> SafeEmitterArg<FreeArgs...>::connect(const Callback::SafeFunctorArg<FreeArgs...>& f1) {
01166   Thread::Mutex::Lock lock{mutex};
01167   emission_list.push_back(ListItem{f1, Callback::SafeFunctorArg<int*>()});
01168   return f1;
01169 }
01170 
01171 template <class... FreeArgs>
01172 Callback::SafeFunctorArg<FreeArgs...> SafeEmitterArg<FreeArgs...>::connect(const Callback::SafeFunctorArg<FreeArgs...>& f1, Releaser& r) {
01173   // In this method:
01174   // f1 is the functor we execute when we emit()
01175   // f2 is the functor we execute in our destructor if we are destroyed before the
01176   // remote object is
01177   // f3 is the functor the remote object executes in its Releaser if it is destroyed
01178   // before we are, or if Releaser::operator=() is called
01179 
01180   Callback::SafeFunctor f3{Callback::make_ref(*this, &SafeEmitterArg<FreeArgs...>::tracking_disconnect, f1)};
01181   Callback::SafeFunctorArg<int*> f2{Callback::make_ref(r, &Releaser::try_remove, f3)};
01182   // we can't call Releaser::add() when holding our mutex or we will
01183   // get out of order locking, as Releaser's mutex is acquired in that
01184   // method, and we don't need to do so
01185   r.add(f3);
01186   Thread::Mutex::Lock lock{mutex};
01187   try {
01188     emission_list.push_back(ListItem{f1, f2});
01189   }
01190   catch (...) {
01191     mutex.unlock();
01192     r.remove(f3);
01193     mutex.lock();
01194     throw;
01195   }
01196   return f1;
01197 }
01198 
01199 template <class... FreeArgs>
01200 void SafeEmitterArg<FreeArgs...>::disconnect(const Callback::SafeFunctorArg<FreeArgs...>& arg) {
01201   // in theory, we could have connected the same functor object more than
01202   // once, so cater for that as well as Releaser::try_remove() failing
01203   Thread::Mutex::Lock lock{mutex};
01204   auto iter = emission_list.begin();
01205   for(;;) {
01206     /*
01207     // gcc-4.4 doesn't support lambdas:
01208     iter = std::find_if(iter, emission_list.end(),
01209                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
01210     */
01211     // so use a local struct and std::bind:
01212     struct Pred {
01213       static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
01214         return (p.f1 == f);
01215       }
01216     };
01217     iter = std::find_if(iter, emission_list.end(),
01218                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
01219     if (iter != emission_list.end()) {
01220       int result = 0; // f2 might be a no-op
01221       // remove ourselves from the remote Releaser object
01222       (iter->f2)(&result);
01223       if (!result) { // we got the Releaser mutex lock or no-op
01224         // now remove this item from emission_list
01225         iter = emission_list.erase(iter);
01226       }
01227       else {
01228         mutex.unlock();
01229         // spin nicely
01230 #ifdef CGU_USE_SCHED_YIELD
01231         sched_yield();
01232 #else
01233         usleep(10);
01234 #endif
01235         mutex.lock();
01236         // start again at the beginning - we have released the mutex
01237         // so our iterator may have become invalid
01238         iter = emission_list.begin();
01239       }
01240     }
01241     else break;
01242   }
01243 }
01244 
01245 // tracking disconnect() is the same as disconnect(), except that we do not
01246 // execute f2 as the remote Releaser object will destroy its own functors
01247 // in that case
01248 template <class... FreeArgs>
01249 void SafeEmitterArg<FreeArgs...>::tracking_disconnect(const Callback::SafeFunctorArg<FreeArgs...>& arg) {
01250   Thread::Mutex::Lock lock{mutex};
01251   auto iter = emission_list.begin();
01252   for (;;) {
01253     // gcc-4.4 doesn't support lambdas:
01254     /*
01255     iter = std::find_if(iter, emission_list.end(),
01256                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
01257     */
01258     // so use a local struct and std::bind:
01259     struct Pred {
01260       static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
01261         return (p.f1 == f);
01262       }
01263     };
01264     iter = std::find_if(iter, emission_list.end(),
01265                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
01266     if (iter != emission_list.end()) {
01267       // remove this item from emission_list
01268       iter = emission_list.erase(iter);
01269     }
01270     else break;
01271   }
01272 }
01273 
01274 template <class... FreeArgs>
01275 void SafeEmitterArg<FreeArgs...>::block(const Callback::SafeFunctorArg<FreeArgs...>& arg) {
01276   // in theory, we could have connected the same functor object
01277   // more than once, so cater for that
01278   Thread::Mutex::Lock lock{mutex};
01279   auto iter = emission_list.begin();
01280   for (;;) {
01281     // gcc-4.4 doesn't support lambdas:
01282     /*
01283     iter = std::find_if(iter, emission_list.end(),
01284                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
01285     */
01286     // so use a local struct and std::bind:
01287     struct Pred {
01288       static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
01289         return (p.f1 == f);
01290       }
01291     };
01292     iter = std::find_if(iter, emission_list.end(),
01293                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
01294     if (iter != emission_list.end()) {
01295       iter->blocked = true;
01296       ++iter;
01297     }
01298     else break;
01299   }
01300 }
01301 
01302 template <class... FreeArgs>
01303 void SafeEmitterArg<FreeArgs...>::unblock(const Callback::SafeFunctorArg<FreeArgs...>& arg) {
01304   // in theory, we could have connected the same functor object
01305   // more than once, so cater for that
01306   Thread::Mutex::Lock lock{mutex};
01307   auto iter = emission_list.begin();
01308   for (;;) {
01309     // gcc-4.4 doesn't support lambdas:
01310     /*
01311     iter = std::find_if(iter, emission_list.end(),
01312                         [&arg](const ListItem& p) -> bool {return p.f1 == arg;});
01313     */
01314     // so use a local struct and std::bind:
01315     struct Pred {
01316       static bool pred(const ListItem& p, const Callback::SafeFunctorArg<FreeArgs...>& f) {
01317         return (p.f1 == f);
01318       }
01319     };
01320     iter = std::find_if(iter, emission_list.end(),
01321                         std::bind(Pred::pred, std::placeholders::_1, std::ref(arg)));
01322     if (iter != emission_list.end()) {
01323       iter->blocked = false;
01324       ++iter;
01325     }
01326     else break;
01327   }
01328 }
01329 
01330 } // namespace Cgu
01331 
01332 #endif // EMITTER_H