Hi Adam, Sorry for the long delay in replying.
You are correct that MessageBuilder is *not* thread-safe. For example, memory allocation within a MessageBuilder allocates sequentially out of a pre-allocated memory segment, and the allocation counter is not protected by any locks. The POCS idea hasn't been implemented yet, unfortunately. I think you will need each task to have its own MessageBuilder where it constructs its particular sub-message (though it might as well be the root of the task's MessageBuilder). Then, when you construct the overall message, you'll need to copy the sub-messages into place. E.g.: mergedBuilder.getRoot<MergedMessage>.setTask1(task1Builder.getRoot<Task1Message>()); -Kenton On Fri, Jan 27, 2017 at 7:53 PM, <[email protected]> wrote: > Had a few spare hours to have another bash at it. > > In the seems-to-work-but-I-have-no-idea-what-I'm-doing category… > > template <typename T> > class SharedOrphan { > public: > SharedOrphan(std::shared_ptr<capnp::MallocMessageBuilder> mb, capnp:: > Orphan<T>& orphan) : > message_builder(mb), orphan(std::move(orphan)) > {}; > > inline capnp::BuilderFor<T> get() { > return orphan.get(); > }; > > inline capnp::ReaderFor<T> getReader() const { > return orphan.getReader(); > }; > > private: > std::shared_ptr<capnp::MallocMessageBuilder> message_builder; > capnp::Orphan<T> orphan; > }; > > SharedOrphan<::Status::Amp> amp_status() { > std::shared_ptr<capnp::MallocMessageBuilder> mb = std::shared_ptr< > capnp::MallocMessageBuilder>(new capnp::MallocMessageBuilder()); > //std::make_shared<capnp::MallocMessageBuilder>(); > > auto amp_status_o = mb->getOrphanage().newOrphan<::Status::Amp>(); > auto amp_status = amp_status_o.get(); > > auto zones = amp_status.initZones(6); > > for (auto z: zones) { > z.setId("zone ID"); > z.setVolume(10); > } > > return SharedOrphan<::Status::Amp>(mb, amp_status_o); > } > > > SharedOrphan<::Status::HDMI> hdmi_status() { > std::shared_ptr<capnp::MallocMessageBuilder> mb = std::shared_ptr< > capnp::MallocMessageBuilder>(new capnp::MallocMessageBuilder()); > //std::make_shared<capnp::MallocMessageBuilder>(); > > auto hdmi_status_o = mb->getOrphanage().newOrphan<::Status::HDMI>(); > > return SharedOrphan<::Status::HDMI>(mb, hdmi_status_o); > } > > > void broadcast_status() { > capnp::MallocMessageBuilder mb; > > auto status = mb.initRoot<Status>(); > > auto amp_status_f = boost::async(boost::launch::async, amp_status). > share(); > auto hdmi_status_f = boost::async(boost::launch::async, hdmi_status). > share(); > > auto all_f = boost::when_all(amp_status_f, hdmi_status_f); > auto str = all_f.then([&](decltype(all_f)) { > > status.setAmp(amp_status_f.get().getReader()); > status.setHdmi(hdmi_status_f.get().getReader()); > > return status; > > }).get().toString(); > > std::cout << str.flatten().cStr() << std::endl; > } > > > The resulting message is built correctly. And I'm assuming that since I'm > passing around both the Orphan and the backing MessageBuilder, that there > are no use-after-free issues with this. > > - Adam > > -- > 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. > -- 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.
