Boost logo

Boost :

From: Douglas Paul Gregor (gregod_at_[hidden])
Date: 2002-07-12 10:59:55


> (3) Next Step?
>
> I don't fully understand how the slot_call_iterator
> works. However, it is obvious that the iterators
> passed to doJob are not valid after
> custom_combiner::operator() has returned. Would it be
> possible (within the combiner) to obtain an underlying
> boost::function for each slot-call from the
> slot_call_iterators? Perhaps this function object
> could be passed to the worker-threads.
>
> Any other suggestions would be greatly appreciated.
>
> Regards,
> Niall.

The reason that the slot_call_iterators are not valid when the combiner
finishes is that the arguments passed from the signal invocation to each
of the slots are stored on the stack; thus, if we try to call the function
object referred to by *sc_iter after the combiner has terminated, the
arguments it refers to no longer exist.

I would suggest that the function objects themselves be asynchronous, so
that invoking a slot spawns a new thread that executes the target
function. An "asynchronous" wrapper could be defined like this:

template<typename F, typename R = typename F::result_type>
struct asynchronous {
  typedef R result_type;

  asynchronous(F f) : f_(f) {}

  // for N=0..some number
  template<typename T1, typename T2, ..., typename TN>
  R operator()(const T1& t1, const T2& t2, ..., const TN& tn)
  {
    return start_a_thread(boost::bind(f, t1, t2, ..., tn));
  }

  F f_;
};

There are a few options to make all slots be automatically wrapped in the
appropriate asynchronous wrapper: the first is to not use signal::connect
directly, but to use a wrapper function that wraps "asynchronous<R>"
around each function object before calling connect.

The second option is to replace the SlotFunction template parameter of the
signal class, which defaults to boost::functionN<R, T1, T2, ..., TN>, with
something like asynchronous<boost::functionN<R, T1, T2, ..., TN> >.
Boost.Function provides the polymorphism, but the asynchronous wrapper
provides the thread start. I think this is my preferred method, and if it
works to your satisfaction thank Peter Dimov for suggesting the
SlotFunction parameter :)

In either case, the combiner need not change.

        Doug


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk