On Tue, 2016-03-22 at 21:52 +0100, Olivier Mallassi wrote:
> hello all
> 
> I have to say I am far from being fluent in c++ but one thing we
> really
> like about proton is that it has no dependency and can be used in
> legacy
> code
> 
> I do not know if the boost::function option will drive a dependency
> to
> boost but this is maybe something to take into account.
> 
> Again, I may be wrong

Not wrong at all. We definitely can do *something* c++03 compatible to
make this usable but it will not be as pretty. The simple approaches
have overhead (heap-allocated function objects) and the performant
approaches are the same as boost::function and std::function, which we
don't want to re-implement.

So my view would be we support boost::function, std::function as the
"right"  way to do it, and provide a virtual operator() approach for
the desperate.

Note we can't use the simple and popular template functor approach: 

    template <class F> inject(F f);

Because that approach only works when you are going to call f within
the body of the template inject<> function. Inject has to *store* the
function and all its bound parameters somewhere (and be able to store
*different types* of function/parameter at the same place) so we can
execute it elsewhere later. That's what the cleverness of std::function
and boost::function is all about - a single compile-time type that can
store different function and argument types at run-time.

> 
> Cheers
> 
> Olivier
> 
> On Monday, 21 March 2016, Alan Conway <[email protected]> wrote:
> 
> > 
> > On Thu, 2016-03-17 at 17:19 -0400, Andrew Stitcher wrote:
> > > 
> > > On Thu, 2016-03-17 at 17:09 -0400, Alan Conway wrote:
> > > > 
> > > > 
> > > > The proton::container is single threaded, once you call run()
> > > > you
> > > > can't
> > > > interact with it from other threads.
> > > > 
> > > > I'd like to propose a "function injection" interface. I think
> > > > the
> > > > analogous thing could be done for all the languages. The Go
> > > > binding
> > > > already has this mechanism.
> > > > 
> > > > The idea is to provide a thread safe call that injects a simple
> > > > "callable" object with no parameters and no return value.
> > > > 
> > > > In  C++11 this is easy to do:
> > > > 
> > > > class container {
> > > >     void inject(std::function<void()>)
> > > > }
> > > > 
> > > > Semantics: calling inject() will queue the injected function to
> > > > be
> > > > called as soon as is reasonable in the run() thread.
> > > This is definitely the interface I was thinking of.
> > > 
> > > I'm not clear exactly how the context carrying through the event
> > > queue
> > > works though to be honest.
> > So there are two issues:
> > 
> > 1. which event loop are you injecting into. I think once we have
> > connections in more than one thread we'll need to inject into a
> > specific connection, not just into the container. Something like
> > 
> >     myconnection.driver().inject(...)
> > 
> > In a single-threaded container, each connection could return the
> > same
> > (container level) driver but in a multi-threaded container each
> > connection would potentially have its own driver. In fact we could
> > provide a driver() on each endpoint and walk up the containment
> > hierarchy, so link::driver() would return its connection's driver
> > etc.
> > 
> > 2. how to supply context to the function being called. That can be
> > done
> > by binding arguments, so for example:
> > 
> >   sender s =
> > myconnection.driver().inject(std::bind(connection::open_sender,
> > myconnection, "foo", ...)
> >   s.driver().inject(std::bind(sender::send, s, mymsg...)
> > 
> > After only a few lines of this you want something like Gordon's
> > BlockingConnection interface, I would see this as the enabler for
> > implementing that.
> > 
> > > 
> > > > 
> > > > In C++03 we can support the functionality in a clunky way that
> > > > is
> > > > not
> > > > very efficient or easy to use, but works:
> > > It's actually exactly as efficient in principle as it does the
> > > same
> > > thing without the decent syntax!
> > Not unless we re-implement boost::function or std::function. We
> > need a
> > copyable, non-template type for functors that we can store where it
> > can
> > be picked up by another thread, which is hard. There is an easy,
> > ugly
> > way using pointers to base classes with virtual functions but it
> > involves allocations for every inject, refcounting or some other
> > tricksy memory mnagement.
> > 
> > > 
> > > 
> > > My objection to this is that I don't think this precise proposal
> > > would
> > > allow you to use a boost::function<> and tbh that's the only way
> > > I
> > > would do this sort of thing in '03.
> > I think we have 3 options and we need to decide which/how many to
> > offer:
> > 
> > - std::function
> > - boost::function
> > - clunky base-class pointers
> > 
> > Less is better for us :) I think you're right that boost::function
> > might be a better second choice than base class pointers since
> > that's
> > very widely available.
> > 
> > 
> > -----------------------------------------------------------------
> > ----
> > To unsubscribe, e-mail: [email protected]
> > <javascript:;>
> > For additional commands, e-mail: [email protected]
> > <javascript:;>
> > 
> > 

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to