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]
For additional commands, e-mail: [email protected]

Reply via email to