fix: make router socket non-blocking to prevent poll loop stalls
Validate and Test / validate-patches (push) Failing after 13s

This commit is contained in:
2026-06-24 04:45:15 -07:00
parent 31bd1d497c
commit f70a8701c9
46 changed files with 47584 additions and 1 deletions
+135
View File
@@ -0,0 +1,135 @@
/*
This file is part of the Arduino_RPClite library.
Copyright (c) 2025 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef RPCLITE_WRAPPER_H
#define RPCLITE_WRAPPER_H
#include <string>
#include "error.h"
#include "rpclite_utils.h"
using namespace RpcUtils::detail;
#ifdef HANDLE_RPC_ERRORS
#include <stdexcept>
#endif
class IFunctionWrapper {
public:
virtual ~IFunctionWrapper() = default;
virtual bool operator()(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) = 0;
};
template<typename F>
class RpcFunctionWrapper;
template<typename R, typename... Args>
class RpcFunctionWrapper<std::function<R(Args...)>>: public IFunctionWrapper {
public:
explicit RpcFunctionWrapper(std::function<R(Args...)> func) : _func(func) {}
R operator()(Args... args) {
return _func(args...);
}
bool operator()(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) override {
MsgPack::object::nil_t nil;
#ifdef HANDLE_RPC_ERRORS
try {
#endif
// First check the parameters size
if (!unpacker.isArray()){
RpcError error(MALFORMED_CALL_ERR, "Unserializable parameters array");
packer.serialize(error, nil);
return false;
}
MsgPack::arr_size_t param_size;
unpacker.deserialize(param_size);
if (param_size.size() < sizeof...(Args)){
RpcError error(MALFORMED_CALL_ERR, "Missing call parameters (WARNING: Default param resolution is not implemented)");
packer.serialize(error, nil);
return false;
}
if (param_size.size() > sizeof...(Args)){
RpcError error(MALFORMED_CALL_ERR, "Too many parameters");
packer.serialize(error, nil);
return false;
}
const int res = handle_call(unpacker, packer);
if (res<0) {
MsgPack::str_t err_msg = "Wrong type parameter in position: ";
#ifdef ARDUINO
err_msg += String(TYPE_ERROR-res);
#else
err_msg += std::to_string(TYPE_ERROR-res);
#endif
RpcError error(MALFORMED_CALL_ERR, err_msg);
packer.serialize(error, nil);
return false;
}
return true;
#ifdef HANDLE_RPC_ERRORS
} catch (const std::exception& e) {
// Should be specialized according to the exception type
RpcError error(GENERIC_ERR, "RPC error");
packer.serialize(error, nil);
return false;
}
#endif
}
private:
std::function<R(Args...)> _func;
template<typename Dummy = R>
typename std::enable_if<std::is_void<Dummy>::value, int>::type
handle_call(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) {
//unpacker not ready if deserialization fails at this point
std::tuple<Args...> args;
const int res = deserialize_tuple(unpacker, args);
if (res<0) return res;
MsgPack::object::nil_t nil;
invoke_with_tuple(_func, args, arx::stdx::make_index_sequence<sizeof...(Args)>{});
packer.serialize(nil, nil);
return 0;
}
template<typename Dummy = R>
typename std::enable_if<!std::is_void<Dummy>::value, int>::type
handle_call(MsgPack::Unpacker& unpacker, MsgPack::Packer& packer) {
//unpacker not ready if deserialization fails at this point
std::tuple<Args...> args;
const int res = deserialize_tuple(unpacker, args);
if (res<0) return res;
MsgPack::object::nil_t nil;
R out = invoke_with_tuple(_func, args, arx::stdx::make_index_sequence<sizeof...(Args)>{});
packer.serialize(nil, out);
return 0;
}
};
template<typename F, typename Signature = typename arx::function_traits<typename std::decay<F>::type>::function_type>
auto wrap(F&& f) -> RpcFunctionWrapper<Signature>* {
return new RpcFunctionWrapper<Signature>(std::forward<F>(f));
};
#endif