Skip to content

Commit

Permalink
#2212: callback: fix problem with Args/Params conflict incorrect mess…
Browse files Browse the repository at this point in the history
…age type
  • Loading branch information
lifflander committed Nov 29, 2023
1 parent 05bb801 commit ae4bae5
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/vt/pipe/callback/cb_union/cb_raw_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ struct CallbackTyped : CallbackRawBaseSingle {

template <typename... Params>
void sendTuple(std::tuple<Params...> tup) {
using MsgT = messaging::ParamMsg<std::tuple<std::decay_t<Params>...>>;
using Trait = CBTraits<Args...>;
using MsgT = messaging::ParamMsg<typename Trait::TupleType>;
auto msg = vt::makeMessage<MsgT>();
msg->setParams(std::move(tup));
CallbackRawBaseSingle::sendMsg<MsgT>(msg);
Expand All @@ -242,10 +243,30 @@ struct CallbackTyped : CallbackRawBaseSingle {
void send(Params&&... params) {
using Trait = CBTraits<Args...>;
if constexpr (std::is_same_v<typename Trait::MsgT, NoMsg>) {
using MsgT = messaging::ParamMsg<std::tuple<std::decay_t<Params>...>>;
auto msg = vt::makeMessage<MsgT>();
msg->setParams(std::forward<Params>(params)...);
CallbackRawBaseSingle::sendMsg<MsgT>(msg);
// We have to go through some tricky code to make the MsgProps case work
// If we use the type for Params to send, it's possible that we have a
// type mismatch in the actual handler type. A possible edge case is when
// a char const* is sent, but the handler is a std::string. In this case,
// the ParamMsg will be cast incorrectly during the virual dispatch to a
// collection because callbacks don't have the collection type. Thus, the
// wrong ParamMsg will be cast to which requires serialization, leading to
// a failure.
if constexpr (sizeof...(Params) == sizeof...(Args) + 1) {
using MsgT = messaging::ParamMsg<
std::tuple<
std::decay_t<std::tuple_element_t<0, std::tuple<Params...>>>,
std::decay_t<Args>...
>
>;
auto msg = vt::makeMessage<MsgT>();
msg->setParams(std::forward<Params>(params)...);
CallbackRawBaseSingle::sendMsg<MsgT>(msg);
} else {
using MsgT = messaging::ParamMsg<typename Trait::TupleType>;
auto msg = vt::makeMessage<MsgT>();
msg->setParams(std::forward<Params>(params)...);
CallbackRawBaseSingle::sendMsg<MsgT>(msg);
}
} else {
using MsgT = typename Trait::MsgT;
auto msg = makeMessage<MsgT>(std::forward<Params>(params)...);
Expand Down

0 comments on commit ae4bae5

Please sign in to comment.