New issue
Advanced search Search tips

Issue 885916 link

Starred by 1 user

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Move more args on callback for Mojo call.

Project Member Reported by hidehiko@chromium.org, Sep 19

Issue description

Currently

=> (array<uint8> data)

callback type will be mapped to

base::OnceCallback(const std::vector<uint8_t>& data);

cf) https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/generators/mojom_cpp_generator.py?l=606
https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/generators/mojom_cpp_generator.py?l=626

So, in the callback method, the value cannot be passed to other function. E.g., to use in another callback for an async function, it needs to be copied.

void MojoCallback(const std::vector<uint8_t>& data) {
  PostTask(..., base::BindOnce(AsyncFunc, std::vector<uint8_t>(data)));
}

void AsyncFunc(std::vector<uint8_t> data) {
  ...
}

If the size of data is big, this is inefficient, and ideally we should be able to pass the value, as same as we're doing for array<T> where T is non-copyable type.

Stepping back, for simplicity, IMHO, we can pass all values by std::move() for callback.
The additional cost could be move-ctor if it is not necessary to be copied. I'm not very sure if it is negligible or not, though.
If not, another alternative will be using rvalue ref, like

base::Callback(std::vector<uint8_t>&& data);

which has no-overhead, and still movable. The concern here is, rvalue itself is not in chromium style.
cf) https://chromium-cpp.appspot.com/ "Rvalue References".

Ken, WDYT?



 
Components: -Internals>Mojo Internals>Mojo>Bindings
Yeah, we've been wanting to do this for a while. The more general concern is discussed a bit on bug 743121. The idea is, any given mojom type may have different ideal C++ representation depending on context: for argument-passing contexts, strings should be base::StringPiece; but for storage contexts (e.g. struct fields and unserialized message objects) they should remain as std::string.

For arrays I would actually say the correct argument-passing type is a by-value base::span<T> rather than a by-value std::vector<T>. The benefits of using base::span<T> are that it's more generic and there is no risk of callers accidentally incurring extra copies.
would adding an attribute to the parameter allow to disambiguate the context? since it is a bindings-only change, it wouldn't change the wire protocol.
Actually base::span<T> doesn't work well for arrays unless we can restrict it to certain element types. The memory layout of a mojom array<T> is not necessarily the identical to that of a base::span<T> (e.g. consider that mojom array<bool> looks more like std::bitset), so we couldn't expose message bytes directly and would thus require a copy into intermediate storage anyway.

So then the only real problem with your proposal is the fact that callers can accidentally copy array data if they pass an lvalue instead of an rvalue. When we've discussed this in the past though, my conclusion has been that risking accidental extra copies is better than being powerless to avoid guaranteed extra copies.

Also +dcheng who would probably be interested in the discussion.
Re comment #2 - I don't follow your suggestion. If we supported something like this, the bindings generator already has all the context it needs to generate different type usage in different places. There would be no need for additional mojom annotation (and that would be undesirable for other reasons anyway).
Cc: dcheng@chromium.org
And +dcheng for real...
Re #3: if the concern is accidental copy, T&& looks an option as proposed in #0.
The concern is the chromium styleguide, though.

So, here are three players.
- Accidental copy risk (in callee).
- Efficiency (requires copy in callbacks).
- Chromium style guide.

And we can take two, but not three...? WDYT?
Using T&& seems problematic. I still think passing by value and risking accidental copy is the best option.

Keep in mind though, this discussion is essentially academic for now. Changing the generated signatures is a massive undertaking and the actual value of doing so is probably marginal.

Until we have someone able to devote several weeks of their time to incrementally converting all bindings users to new signatures, it's not going to happen.
Cc: -roc...@chromium.org rockot@google.com
Cc: -lhchavez@chromium.org

Sign in to add a comment