Are you compiling with c++14 features enabled? Usually the `-std=c++1y`
flag will do that.

- David


On Tue, May 31, 2016 at 11:27 AM, Abhishek Balaji Radhakrishnan <
abhishek.r...@gmail.com> wrote:

> Hi David and Kenton,
>
> I have a similar usecase for a project and I am trying to replicate this
> example to see how it works, but the server code in this case is throwing
> errors. Not sure what might have changed over time.
>
> A gist of the error is as follows:
> entry_ss.c++: In member function ‘void
> EntryPusher::pushEntryInternal(int)’:
> entry_ss.c++:29:53: error: parameter declared ‘auto’
>      taskSet.add(entryReq.send().then([this, i](auto x) {
>                                                      ^
> entry_ss.c++: In lambda function:
> entry_ss.c++:34:69: error: parameter declared ‘auto’
>              taskSet.add(processor.doneRequest().send().then([](auto x)
> {}));
>                                                                      ^
> In file included from /usr/local/include/kj/async.h:29:0,
>                  from /usr/local/include/capnp/capability.h:33,
>                  from /usr/local/include/capnp/rpc.h:29,
>                  from /usr/local/include/capnp/ez-rpc.h:29,
>                  from entry_ss.c++:5:
>
> ...
>
>
> I see that the pushEntryInternal() is causing the problem with the then()
> semantics - not sure how to fix this:
>
> void pushEntryInternal(int i) {
>     auto entryReq = processor.processRequest();
>     entryReq.getEntry().setData(i);
>     taskSet.add(entryReq.send().then([this, i](auto x) {
>           usleep(500000);
>           if (i > 0) {
>             pushEntryInternal(i - 1);
>           } else {
>             taskSet.add(processor.doneRequest().send().then([](auto x)
> {}));
>           }
>         }));
>   }
>
>
> Thanks,
> Abhishek
>
>
>
> On Tuesday, 21 October 2014 21:47:21 UTC-4, David Renshaw wrote:
>>
>> Ouch. Looks like `GC_apply_to_all_blocks()` doesn't give you any chance
>> to yield control. So though you can queue up as many sends as you like,
>> they won't get executed until `GC_apply_to_all_blocks()` completes. You'd
>> be better off just buffering the GCEntries in a list.
>>
>> If you don't want to buffer all of the GCEntry objects in memory before
>> sending them, then I think you're forced to put the call to
>> `GC_apply_to_all_blocks()` in a separate thread. You could communicate with
>> that thread using a socketpair, receiving the GCEntries back as a raw
>> stream of Cap'n Proto messages, and then forwarding the entries to the
>> `sendGCEntry()` method. The read methods declared in serialize-async.h
>> allow you to do this in a way that plays nicely with the event loop.
>>
>>
>> -David
>>
>>
>> On Tue, Oct 21, 2014 at 6:51 PM, Turing Eret <er...@lambdacalcul.us>
>> wrote:
>>
>>> Easier to do in theory than practice. In my actual program, my
>>> equivalent of pushEntry() is this:
>>>
>>> void processMonoObjects(mono_object_processor f, void* user_data)
>>>
>>> {
>>>
>>>     mono_gc_disable();
>>>
>>>
>>>
>>>     MonoHeapProcessorState state;
>>>
>>>
>>>
>>>     state.vtables = getAllVTables();
>>>
>>>     state.processor = f;
>>>
>>>     state.user_data = user_data;
>>>
>>>
>>>
>>>     GC_apply_to_all_blocks(blockProcessor, (word)&state);
>>>
>>>
>>>
>>>     mono_gc_enable();
>>>
>>> }
>>>
>>> where mono_object_processor is defined as this:
>>>
>>> typedef void (__cdecl *mono_object_processor)(MonoObject* obj, void*
>>> user_data);
>>>
>>>
>>> Now, my equivalent of pushEntryInternal() is one of those
>>> mono_object_processor functions and GC_apply_to_all_blocks() calls that
>>> function on all the blocks known by the GC. Unfortunately, that isn't
>>> something I wrote nor something I can change. I attempted this:
>>>
>>> void scrapHeapProcessor(MonoObject* obj, HeapScraper* heapScraperPtr)
>>>
>>> {
>>>
>>>     heapScraperPtr->promise = heapScraperPtr->promise.then([=]()
>>>
>>>                                                            {
>>>
>>>
>>>  heapScraperPtr->sendGCEntry(obj);
>>>
>>>                                                            });
>>>
>>> }
>>>
>>>
>>> void HeapScraper::startScraping()
>>>
>>> {
>>>
>>>     processMonoObjects((mono_object_processor)scrapHeapProcessor, this);
>>>
>>>     taskSet.add(std::move(promise));
>>>
>>> }
>>>
>>>
>>> Unfortunately, this exploded badly in a stack overflow. Is that what you
>>> were suggesting? Is there a better way to do this that doesn't explode in
>>> my face?
>>>
>>>
>>> Turing
>>>
>>> On Tuesday, 21 October 2014 15:57:02 UTC-6, David Renshaw wrote:
>>>
>>>>
>>>> On Tue, Oct 21, 2014 at 3:59 PM, Turing Eret <er...@lambdacalcul.us>
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>> So, each top-level call of pushEntryInternal() descends through to its
>>>>> base case before going up to the next top-level call of
>>>>> pushEntryInternal(), a depth-first traversal of the tasks. Is there any 
>>>>> way
>>>>> to do that easily?
>>>>>
>>>>
>>>>
>>>> To accomplish that, I would redefine `pushEntryInternal()` so that it
>>>> returns a `kj::Promise<void>`, to be fulfilled when all the entries have
>>>> been pushed. Then I would chain the calls to `pushEntryInternal()` using
>>>> the `then()` method.
>>>>
>>>>
>>>>> PS: On a completely unrelated note, is there a document somewhere
>>>>> showing what languages have plugins currently in development and who is
>>>>> working on the plugin?
>>>>>
>>>>
>>>> Yes: https://kentonv.github.io/capnproto/otherlang.html
>>>>
>>>>
>>>> -David
>>>>
>>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
Visit this group at https://groups.google.com/group/capnproto.

Reply via email to