Boost logo

Boost :

Subject: Re: [boost] [coroutine] interface suggestion
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2012-09-20 06:18:06


On Thu, Sep 20, 2012 at 3:51 AM, Vicente J. Botet Escriba <
vicente.botet_at_[hidden]> wrote:

> Le 19/09/12 21:05, Oliver Kowalke a écrit :
>
> int f( caller_t & c, strg & s, int x) {
>> caller_t::yield_t b = c.bind( s, x); // s and x are now used to
>> store the next calls.
>> b.yield( 7); // alternative b( 7)
>> // here s and x have been reassigned
>> }
>>
>> c.bind() retrieves the addresses of the parameters used to store the
>> values (for each entering of f).
>> only yield_t will provide yield() function.
>>
>> what do you think?
>>
>>
>> This is exactly what I proposed above :) and for the time been this is
> the best interface I have found.

I have issues with this interface, though:
- Why do you need to explicitly bind? If you are required to bind the
arguments of the coroutine-fn anyway, the trampoline might as well do it
for you.
- As you described, you need to provide an alternate interface (i.e. get())
to access the arguments from a nested function anyway. You might as well
make this the only interface.
- Tying the caller_t to an object in the coroutine stack (the parameters),
makes it very hard to move the caller object to another coroutine. This is
important to implement pipelines, where yield does not return to the caller
but the next coroutine in the pipeline.
- Also see below:

> Note that as I commented in some of my first post related to bind, you
> must take care of const and reference parameters in some tricky ways, as
> in order to be able to reassign them you should do some casts. I hope this
> will not cache some undefined behavior.
>

How would you exactly rebind references? I can't see any sane way to do
it. I would expect the following code to work:

int i = 0, j = 0;
coroutine<void(int&)> coro([&](caller_t& caller, int& x) {
               caller.bind(x);
               assert(&x == &i); // ok
               caller.yield();
               assert(&x == &y); // ?????
});

coro(i);
coro(j);

tl;dr: have get() as the only way to access parameters and have the
parameters themselves local variables (i.e. stack allocated) of the calling
context, not of the callee.


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