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 < [email protected]> 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 <[email protected]> >> 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 <[email protected]> >>>> 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 [email protected]. Visit this group at https://groups.google.com/group/capnproto.
