From 53795c74aead4e6021bc788b788f8ed5b4a0166d Mon Sep 17 00:00:00 2001 From: Andrej Rode Date: Mon, 3 Apr 2017 18:49:58 -0700 Subject: uhd: add cut-down rpclib source tree and import tool --- host/lib/deps/rpclib/include/rpc/detail/all.h | 26 ++++ host/lib/deps/rpclib/include/rpc/detail/any.h | 21 +++ .../deps/rpclib/include/rpc/detail/async_writer.h | 86 +++++++++++ host/lib/deps/rpclib/include/rpc/detail/bool.h | 21 +++ host/lib/deps/rpclib/include/rpc/detail/call.h | 92 ++++++++++++ .../deps/rpclib/include/rpc/detail/client_error.h | 39 +++++ host/lib/deps/rpclib/include/rpc/detail/constant.h | 17 +++ .../lib/deps/rpclib/include/rpc/detail/dev_utils.h | 21 +++ .../deps/rpclib/include/rpc/detail/func_tools.h | 26 ++++ .../deps/rpclib/include/rpc/detail/func_traits.h | 77 ++++++++++ host/lib/deps/rpclib/include/rpc/detail/if.h | 16 +++ host/lib/deps/rpclib/include/rpc/detail/invoke.h | 15 ++ .../include/rpc/detail/is_specialization_of.h | 20 +++ host/lib/deps/rpclib/include/rpc/detail/log.h | 159 +++++++++++++++++++++ .../deps/rpclib/include/rpc/detail/make_unique.h | 31 ++++ host/lib/deps/rpclib/include/rpc/detail/not.h | 17 +++ host/lib/deps/rpclib/include/rpc/detail/pimpl.h | 10 ++ host/lib/deps/rpclib/include/rpc/detail/response.h | 119 +++++++++++++++ .../rpclib/include/rpc/detail/server_session.h | 48 +++++++ .../deps/rpclib/include/rpc/detail/thread_group.h | 40 ++++++ host/lib/deps/rpclib/include/rpc/detail/util.h | 19 +++ 21 files changed, 920 insertions(+) create mode 100644 host/lib/deps/rpclib/include/rpc/detail/all.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/any.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/async_writer.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/bool.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/call.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/client_error.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/constant.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/dev_utils.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/func_tools.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/func_traits.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/if.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/invoke.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/is_specialization_of.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/log.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/make_unique.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/not.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/pimpl.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/response.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/server_session.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/thread_group.h create mode 100644 host/lib/deps/rpclib/include/rpc/detail/util.h (limited to 'host/lib/deps/rpclib/include/rpc/detail') diff --git a/host/lib/deps/rpclib/include/rpc/detail/all.h b/host/lib/deps/rpclib/include/rpc/detail/all.h new file mode 100644 index 000000000..5a060bfb0 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/all.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef ALL_H_H8MAAYCG +#define ALL_H_H8MAAYCG + +#include "rpc/detail/invoke.h" +#include "rpc/detail/if.h" +#include "rpc/detail/bool.h" + +namespace rpc { +namespace detail { + +//! \brief This type can be used to check multiple conditions. +//! It will be true_type if all its arguments are true. +template struct all : true_ {}; + +template +struct all + : if_, false_> {}; + +} +} + + + +#endif /* end of include guard: ALL_H_H8MAAYCG */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/any.h b/host/lib/deps/rpclib/include/rpc/detail/any.h new file mode 100644 index 000000000..09ffb81cf --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/any.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef ANY_H_4G3QUOAN +#define ANY_H_4G3QUOAN + +#include "rpc/detail/invoke.h" +#include "rpc/detail/if.h" +#include "rpc/detail/bool.h" + +namespace rpc { +namespace detail { + +//! \brief Evaluates to true_type if any of its arguments is true_type. +template struct any : false_ {}; + +template +struct any : if_> {}; +} +} + +#endif /* end of include guard: ANY_H_4G3QUOAN */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/async_writer.h b/host/lib/deps/rpclib/include/rpc/detail/async_writer.h new file mode 100644 index 000000000..941bb1d8f --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/async_writer.h @@ -0,0 +1,86 @@ +#pragma once + +#ifndef ASYNC_WRITER_H_HQIRH28I +#define ASYNC_WRITER_H_HQIRH28I + +#include +#include "rpc/msgpack.hpp" +#include +#include +#include +#include + +namespace rpc { + +class client; + +namespace detail { + +//! \brief Common logic for classes that have a write queue with async writing. +class async_writer : public std::enable_shared_from_this { +public: + async_writer(boost::asio::io_service *io, + boost::asio::ip::tcp::socket socket) + : socket_(std::move(socket)), write_strand_(*io), exit_(false) {} + + void do_write() { + if (exit_) { + return; + } + auto self(shared_from_this()); + auto &item = write_queue_.front(); + // the data in item remains valid until the handler is called + // since it will still be in the queue physically until then. + boost::asio::async_write( + socket_, boost::asio::buffer(item.data(), item.size()), + write_strand_.wrap( + [this, self](boost::system::error_code ec, std::size_t transferred) { + (void)transferred; + if (!ec) { + write_queue_.pop_front(); + if (write_queue_.size() > 0) { + if (!exit_) { + do_write(); + } + } + } else { + LOG_ERROR("Error while writing to socket: {}", ec); + } + + if (exit_) { + LOG_INFO("Closing socket"); + socket_.shutdown( + boost::asio::ip::tcp::socket::shutdown_both); + socket_.close(); + } + })); + } + + void write(RPCLIB_MSGPACK::sbuffer &&data) { + write_queue_.push_back(std::move(data)); + if (write_queue_.size() > 1) { + return; // there is an ongoing write chain so don't start another + } + + do_write(); + } + + friend class rpc::client; + +protected: + boost::asio::ip::tcp::socket socket_; + boost::asio::strand write_strand_; + std::atomic_bool exit_{false}; + bool exited_ = false; + std::mutex m_exit_; + std::condition_variable cv_exit_; + +private: + std::deque write_queue_; + RPCLIB_CREATE_LOG_CHANNEL(async_writer) +}; + +} /* detail */ +} /* rpc */ + +#endif /* end of include guard: ASYNC_WRITER_H_HQIRH28I */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/bool.h b/host/lib/deps/rpclib/include/rpc/detail/bool.h new file mode 100644 index 000000000..65f37d371 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/bool.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef BOOL_H_QLG6S5XZ +#define BOOL_H_QLG6S5XZ + +#include "rpc/detail/constant.h" + +namespace rpc { +namespace detail { + +template +using bool_ = constant; + +using true_ = bool_; + +using false_ = bool_; + +} +} + +#endif /* end of include guard: BOOL_H_QLG6S5XZ */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/call.h b/host/lib/deps/rpclib/include/rpc/detail/call.h new file mode 100644 index 000000000..b5c9bdce0 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/call.h @@ -0,0 +1,92 @@ +#pragma once + +#ifndef CALL_H_ZXFACADH +#define CALL_H_ZXFACADH + +#include +#include "rpc/detail/func_tools.h" +#include "rpc/detail/invoke.h" +#include "rpc/detail/is_specialization_of.h" + +namespace rpc { +namespace detail { + +//! \brief Calls a functor with argument provided directly +template +auto call(Functor f, Arg &&arg) + -> decltype(f(std::forward(arg))) +{ + return f(std::forward(arg)); +} + + +// Default behaviour is to assume C++11, overriding RPCLIB_CXX_STANDARD can use +// newer standards: +#if RPCLIB_CXX_STANDARD >= 14 + +template +decltype(auto) call_helper(Functor func, std::tuple &¶ms, + std::index_sequence) { + return func(std::get(params)...); +} + +//! \brief Calls a functor with arguments provided as a tuple +template +decltype(auto) call(Functor f, std::tuple &args) { + return call_helper(f, std::forward>(args), + std::index_sequence_for{}); +} + +#else + +// N is number of arguments left in tuple to unpack + +template +struct call_helper +{ + template + static auto call( + Functor f, + std::tuple& args_t, + ArgsF&&... args_f) + -> decltype(call_helper::call( + f, args_t, std::get(args_t), + std::forward(args_f)...)) + { + return call_helper::call( + f, + args_t, + std::get(args_t), + std::forward(args_f)... + ); + } +}; + +template <> +struct call_helper<0> +{ + template + static auto call( + Functor f, + std::tuple&, + ArgsF&&... args_f) + -> decltype(f(std::forward(args_f)...)) + { + return f(std::forward(args_f)...); + } +}; + +//! \brief Calls a functor with arguments provided as a tuple +template +auto call(Functor f, std::tuple& args_t) + -> decltype(call_helper::call(f, args_t)) +{ + return call_helper::call(f, args_t); +} + +#endif + +} +} + +#endif /* end of include guard: CALL_H_ZXFACADH */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/client_error.h b/host/lib/deps/rpclib/include/rpc/detail/client_error.h new file mode 100644 index 000000000..73edd2ebe --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/client_error.h @@ -0,0 +1,39 @@ +#pragma once + +#ifndef RPC_CLIENT_ERROR_H +#define RPC_CLIENT_ERROR_H + +#include +#include + +namespace rpc { +namespace detail { + +//! \brief Describes an error that is the result of a connected client +//! doing something unexpected (e.g. calling a function that does not exist, +//! wrong number of arguments, etc.) +class client_error : public std::exception { +public: + //! \brief Error codes used for signaling back to clients. These are used + //! to produce google-able error messages (since the msgpack-rpc protocol + //! does not define error handling in any more detail than sending an + //! object). + //! \note Care must be taken to keep these codes stable even between major + //! versions. + enum class code : uint16_t { + no_such_function = 1, + wrong_arity = 2, + protocol_error = 4 + }; + + client_error(code c, const std::string &msg); + + const char *what() const noexcept; + +private: + std::string what_; +}; +} +} + +#endif // RPC_CLIENT_ERROR_H diff --git a/host/lib/deps/rpclib/include/rpc/detail/constant.h b/host/lib/deps/rpclib/include/rpc/detail/constant.h new file mode 100644 index 000000000..1c373b3a2 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/constant.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef CONSTANT_H_5CXUYJEW +#define CONSTANT_H_5CXUYJEW + +#include + +namespace rpc { +namespace detail { + +template +struct constant : std::integral_constant {}; + +} +} + +#endif /* end of include guard: CONSTANT_H_5CXUYJEW */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/dev_utils.h b/host/lib/deps/rpclib/include/rpc/detail/dev_utils.h new file mode 100644 index 000000000..325320970 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/dev_utils.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef DEV_UTILS_H_JQSWE2OS +#define DEV_UTILS_H_JQSWE2OS + +#ifdef RPCLIB_LINUX +#include "pthread.h" +#endif + +namespace rpc { +namespace detail { +inline void name_thread(std::string const &name) { + (void)name; +#ifdef RPCLIB_LINUX + pthread_setname_np(pthread_self(), name.c_str()); +#endif +} +} /* detail */ +} /* rpc */ + +#endif /* end of include guard: DEV_UTILS_H_JQSWE2OS */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/func_tools.h b/host/lib/deps/rpclib/include/rpc/detail/func_tools.h new file mode 100644 index 000000000..4f18e482d --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/func_tools.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef FUNC_TOOLS_H_9FNRD4G2 +#define FUNC_TOOLS_H_9FNRD4G2 + +#include "rpc/detail/invoke.h" +#include "rpc/detail/all.h" +#include "rpc/detail/any.h" + +namespace rpc { +namespace detail { + + +enum class enabled {}; + +template +using enable_if = invoke::value, enabled>>; + +template +using disable_if = invoke::value, enabled>>; + + +} +} + +#endif /* end of include guard: FUNC_TOOLS_H_9FNRD4G2 */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/func_traits.h b/host/lib/deps/rpclib/include/rpc/detail/func_traits.h new file mode 100644 index 000000000..1847d99dc --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/func_traits.h @@ -0,0 +1,77 @@ +#pragma once + +#ifndef FUNC_TRAITS_H_HWIWA6G0 +#define FUNC_TRAITS_H_HWIWA6G0 + +#include "rpc/detail/bool.h" + +namespace rpc { +namespace detail { + +template +using is_zero = invoke>; + +template +using nth_type = invoke>>; + +namespace tags { + +// tags for the function traits, used for tag dispatching +struct zero_arg {}; +struct nonzero_arg {}; +struct void_result {}; +struct nonvoid_result {}; + +template struct arg_count_trait { typedef nonzero_arg type; }; + +template <> struct arg_count_trait<0> { typedef zero_arg type; }; + +template struct result_trait { typedef nonvoid_result type; }; + +template <> struct result_trait { typedef void_result type; }; +} + +//! \brief Provides a small function traits implementation that +//! works with a reasonably large set of functors. +template +struct func_traits : func_traits {}; + +template +struct func_traits : func_traits {}; + +template +struct func_traits : func_traits {}; + +template struct func_traits { + using result_type = R; + using arg_count = std::integral_constant; + using args_type = std::tuple::type...>; +}; + +template +struct func_kind_info : func_kind_info {}; + +template +struct func_kind_info : func_kind_info {}; + +template +struct func_kind_info + : func_kind_info {}; + +template struct func_kind_info { + typedef typename tags::arg_count_trait::type args_kind; + typedef typename tags::result_trait::type result_kind; +}; + +template using is_zero_arg = is_zero::arg_count>; + +template +using is_single_arg = + invoke::arg_count == 1, true_, false_>>; + +template +using is_void_result = std::is_void::result_type>; +} +} + +#endif /* end of include guard: FUNC_TRAITS_H_HWIWA6G0 */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/if.h b/host/lib/deps/rpclib/include/rpc/detail/if.h new file mode 100644 index 000000000..7e4cab4f1 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/if.h @@ -0,0 +1,16 @@ +#pragma once + +#ifndef IF_H_1OW9DR7G +#define IF_H_1OW9DR7G + +#include "rpc/detail/invoke.h" + +namespace rpc { +namespace detail { + +template +using if_ = invoke>; +} +} + +#endif /* end of include guard: IF_H_1OW9DR7G */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/invoke.h b/host/lib/deps/rpclib/include/rpc/detail/invoke.h new file mode 100644 index 000000000..4a4915829 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/invoke.h @@ -0,0 +1,15 @@ +#pragma once + +#ifndef INVOKE_H_0CWMPLUE +#define INVOKE_H_0CWMPLUE + +namespace rpc { +namespace detail { + +template +using invoke = typename T::type; + +}} + + +#endif /* end of include guard: INVOKE_H_0CWMPLUE */ diff --git a/host/lib/deps/rpclib/include/rpc/detail/is_specialization_of.h b/host/lib/deps/rpclib/include/rpc/detail/is_specialization_of.h new file mode 100644 index 000000000..c4003cee9 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/detail/is_specialization_of.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef IS_SPECIALIZATION_OF_H_OPZTARVG +#define IS_SPECIALIZATION_OF_H_OPZTARVG + +#include "rpc/detail/bool.h" + +namespace rpc { +namespace detail { + +template