Thanks David. I was on g++ 4.8.4 which I guess doesn't support c++14 features. Upgraded g++ to 6.1.1 and then made the changes that you pointed out - got the server working!
Thanks, Abhishek On Tuesday, 31 May 2016 23:52:11 UTC-4, David Renshaw wrote: > > Weird. It works with clang++ for me, modulo the clang bug we also ran into > here: https://github.com/sandstorm-io/sandstorm/pull/1450 . > > I just tried compiling server.c++ with g++ version 6.1.1 and -std=c++14, > and I got the following error, which is puzzling (is it not actually legal > to call methods on a captured `this`?), but can be fixed by replacing > `pushEntryInternal(i - 1)` with `this->pushEntryInternal(i - 1)`: > > server.c++:32:30: error: cannot call member function ‘void > EntryPusher::pushEntryInternal(int)’ without object > pushEntryInternal(i - 1); > > > However, the only way I was able to get the compiler to emit an error like > the one you're seeing was with the flag `std=c++11`. > > Maybe you could work around the problem by explicitly writing out the type > of the parameter, rather than `auto x`. I think `capnp::Response<EntrySink > ::ProcessResults> x` should work. > > > - David > > On Tue, May 31, 2016 at 11:40 AM, Abhishek Balaji Radhakrishnan < > [email protected] <javascript:>> wrote: > >> 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] >> <javascript:>> 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] <javascript:>> 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.
