Tried that as well, but it doesn't work: c++ -std=c++1y -Wall entry_ss.c++ entry_protocol.capnp.c++ -pthread -I/usr/local/include -pthread -L/usr/local/lib -lcapnp-rpc -lcapnp -lkj-async -lkj -lpthread -o test_server
Any workarounds to this? On Tue, May 31, 2016 at 11:32 AM, David Renshaw <[email protected]> wrote: > 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 >>>>> >>>>> >>> > -- Abhishek -- 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.
