Hi Kenton,

Thanks for the advice.

This is what I ended up with:

template <typename T>
class SharedMessageBuilder {
public:
    SharedMessageBuilder() :
        message_builder(boost::make_shared<capnp::MallocMessageBuilder>())
    {};

    inline capnp::BuilderFor<T> getRoot() const {
        return message_builder->template getRoot<T>();
    };

private:
    boost::shared_ptr<capnp::MallocMessageBuilder> message_builder;
};

Then in each task, I create an instance and fill it out:

auto mb = SharedMessageBuilder<::Status::Amp>();
auto amp_status = mb.getRoot();
…


then in the caller/collector, I copy the data (where amp_status_f, is a
boost::future<SharedMessageBuilder<::Status::Amp>>):

capnp::MallocMessageBuilder message;

auto status = message.initRoot<Status>();
status.setAmp(amp_status_f.get().getRoot().asReader());

Thanks again,
Adam

On Mon, Feb 13, 2017 at 1:13 PM, Kenton Varda <[email protected]> wrote:

> 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 a topic in the
> Google Groups "Cap'n Proto" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/capnproto/IKl9dkt14Ac/unsubscribe.
> To unsubscribe from this group and all its topics, 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.

Reply via email to