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]
