aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/deps/rpclib/include/rpc/detail
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/deps/rpclib/include/rpc/detail')
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/all.h26
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/any.h21
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/async_writer.h86
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/bool.h21
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/call.h92
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/client_error.h39
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/constant.h17
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/dev_utils.h21
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/func_tools.h26
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/func_traits.h77
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/if.h16
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/invoke.h15
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/is_specialization_of.h20
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/log.h159
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/make_unique.h31
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/not.h17
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/pimpl.h10
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/response.h119
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/server_session.h48
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/thread_group.h40
-rw-r--r--host/lib/deps/rpclib/include/rpc/detail/util.h19
21 files changed, 920 insertions, 0 deletions
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 <typename... T> struct all : true_ {};
+
+template <typename H, typename... T>
+struct all<H, T...>
+ : if_<H, all<T...>, 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 <typename... T> struct any : false_ {};
+
+template <typename H, typename... T>
+struct any<H, T...> : if_<H, true_, any<T...>> {};
+}
+}
+
+#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 <boost/asio.hpp>
+#include "rpc/msgpack.hpp"
+#include <condition_variable>
+#include <deque>
+#include <memory>
+#include <thread>
+
+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<async_writer> {
+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<RPCLIB_MSGPACK::sbuffer> 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<bool B>
+using bool_ = constant<bool, B>;
+
+using true_ = bool_<true>;
+
+using false_ = bool_<false>;
+
+}
+}
+
+#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 <tuple>
+#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 <typename Functor, typename Arg>
+auto call(Functor f, Arg &&arg)
+ -> decltype(f(std::forward<Arg>(arg)))
+{
+ return f(std::forward<Arg>(arg));
+}
+
+
+// Default behaviour is to assume C++11, overriding RPCLIB_CXX_STANDARD can use
+// newer standards:
+#if RPCLIB_CXX_STANDARD >= 14
+
+template <typename Functor, typename... Args, std::size_t... I>
+decltype(auto) call_helper(Functor func, std::tuple<Args...> &&params,
+ std::index_sequence<I...>) {
+ return func(std::get<I>(params)...);
+}
+
+//! \brief Calls a functor with arguments provided as a tuple
+template <typename Functor, typename... Args>
+decltype(auto) call(Functor f, std::tuple<Args...> &args) {
+ return call_helper(f, std::forward<std::tuple<Args...>>(args),
+ std::index_sequence_for<Args...>{});
+}
+
+#else
+
+// N is number of arguments left in tuple to unpack
+
+template <size_t N>
+struct call_helper
+{
+ template <typename Functor, typename... ArgsT, typename... ArgsF>
+ static auto call(
+ Functor f,
+ std::tuple<ArgsT...>& args_t,
+ ArgsF&&... args_f)
+ -> decltype(call_helper<N-1>::call(
+ f, args_t, std::get<N-1>(args_t),
+ std::forward<ArgsF>(args_f)...))
+ {
+ return call_helper<N-1>::call(
+ f,
+ args_t,
+ std::get<N-1>(args_t),
+ std::forward<ArgsF>(args_f)...
+ );
+ }
+};
+
+template <>
+struct call_helper<0>
+{
+ template <typename Functor, typename... ArgsT, typename... ArgsF>
+ static auto call(
+ Functor f,
+ std::tuple<ArgsT...>&,
+ ArgsF&&... args_f)
+ -> decltype(f(std::forward<ArgsF>(args_f)...))
+ {
+ return f(std::forward<ArgsF>(args_f)...);
+ }
+};
+
+//! \brief Calls a functor with arguments provided as a tuple
+template <typename Functor, typename... ArgsT>
+auto call(Functor f, std::tuple<ArgsT...>& args_t)
+ -> decltype(call_helper<sizeof...(ArgsT)>::call(f, args_t))
+{
+ return call_helper<sizeof...(ArgsT)>::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 <stdexcept>
+#include <cstdint>
+
+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 <type_traits>
+
+namespace rpc {
+namespace detail {
+
+template<typename T, T I>
+struct constant : std::integral_constant<T, I> {};
+
+}
+}
+
+#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 <typename... C>
+using enable_if = invoke<std::enable_if<all<C...>::value, enabled>>;
+
+template <typename... C>
+using disable_if = invoke<std::enable_if<!any<C...>::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 <int N>
+using is_zero = invoke<std::conditional<(N == 0), true_, false_>>;
+
+template <int N, typename... Ts>
+using nth_type = invoke<std::tuple_element<N, std::tuple<Ts...>>>;
+
+namespace tags {
+
+// tags for the function traits, used for tag dispatching
+struct zero_arg {};
+struct nonzero_arg {};
+struct void_result {};
+struct nonvoid_result {};
+
+template <int N> struct arg_count_trait { typedef nonzero_arg type; };
+
+template <> struct arg_count_trait<0> { typedef zero_arg type; };
+
+template <typename T> struct result_trait { typedef nonvoid_result type; };
+
+template <> struct result_trait<void> { typedef void_result type; };
+}
+
+//! \brief Provides a small function traits implementation that
+//! works with a reasonably large set of functors.
+template <typename T>
+struct func_traits : func_traits<decltype(&T::operator())> {};
+
+template <typename C, typename R, typename... Args>
+struct func_traits<R (C::*)(Args...)> : func_traits<R (*)(Args...)> {};
+
+template <typename C, typename R, typename... Args>
+struct func_traits<R (C::*)(Args...) const> : func_traits<R (*)(Args...)> {};
+
+template <typename R, typename... Args> struct func_traits<R (*)(Args...)> {
+ using result_type = R;
+ using arg_count = std::integral_constant<std::size_t, sizeof...(Args)>;
+ using args_type = std::tuple<typename std::decay<Args>::type...>;
+};
+
+template <typename T>
+struct func_kind_info : func_kind_info<decltype(&T::operator())> {};
+
+template <typename C, typename R, typename... Args>
+struct func_kind_info<R (C::*)(Args...)> : func_kind_info<R (*)(Args...)> {};
+
+template <typename C, typename R, typename... Args>
+struct func_kind_info<R (C::*)(Args...) const>
+ : func_kind_info<R (*)(Args...)> {};
+
+template <typename R, typename... Args> struct func_kind_info<R (*)(Args...)> {
+ typedef typename tags::arg_count_trait<sizeof...(Args)>::type args_kind;
+ typedef typename tags::result_trait<R>::type result_kind;
+};
+
+template <typename F> using is_zero_arg = is_zero<func_traits<F>::arg_count>;
+
+template <typename F>
+using is_single_arg =
+ invoke<std::conditional<func_traits<F>::arg_count == 1, true_, false_>>;
+
+template <typename F>
+using is_void_result = std::is_void<typename func_traits<F>::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 <typename C, typename T, typename F>
+using if_ = invoke<std::conditional<C::value, T, F>>;
+}
+}
+
+#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<typename T>
+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 <template <typename...> class Templ, typename T>
+struct is_specialization_of : false_ {};
+
+template <template <typename...> class Templ, typename... T>
+struct is_specialization_of<Templ, Templ<T...>> : true_ {};
+
+}
+} /* rpc */
+
+#endif /* end of include guard: IS_SPECIALIZATION_OF_H_OPZTARVG */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/log.h b/host/lib/deps/rpclib/include/rpc/detail/log.h
new file mode 100644
index 000000000..0d5e51c61
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/log.h
@@ -0,0 +1,159 @@
+#pragma once
+
+#ifndef LOG_H_SPSC31OG
+#define LOG_H_SPSC31OG
+
+#ifdef RPCLIB_ENABLE_LOGGING
+
+#include "format.h"
+#include <chrono>
+#include <cstdlib>
+#include <iomanip>
+#include <mutex>
+#include <sstream>
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <time.h>
+
+#ifdef _MSC_VER
+#include <Windows.h>
+#endif
+
+namespace rpc {
+namespace detail {
+class logger {
+public:
+ static logger &instance() {
+ static logger inst;
+ return inst;
+ }
+
+ template <typename... Args>
+ void trace(const char *channel, const char *file, const char *func,
+ std::size_t line, const char *msg, Args... args) {
+ (void)func;
+ basic_log("TRACE", channel,
+ RPCLIB_FMT::format("{} ({}:{})",
+ RPCLIB_FMT::format(msg, args...), file,
+ line));
+ }
+
+ template <typename... Args>
+ void debug(const char *channel, const char *file, const char *func,
+ std::size_t line, const char *msg, Args... args) {
+ (void)func;
+ basic_log("DEBUG", channel,
+ RPCLIB_FMT::format("{} ({}:{})",
+ RPCLIB_FMT::format(msg, args...), file,
+ line));
+ }
+
+ template <typename... Args>
+ void warn(const char *channel, const char *msg, Args... args) {
+ basic_log("WARN", channel, RPCLIB_FMT::format(msg, args...));
+ }
+
+ template <typename... Args>
+ void error(const char *channel, const char *msg, Args... args) {
+ basic_log("ERROR", channel, RPCLIB_FMT::format(msg, args...));
+ }
+
+ template <typename... Args>
+ void info(const char *channel, const char *msg, Args... args) {
+ basic_log("INFO", channel, RPCLIB_FMT::format(msg, args...));
+ }
+
+private:
+ logger() {}
+
+#ifdef _MSC_VER
+ static std::string now() {
+ std::stringstream ss;
+ SYSTEMTIME t;
+ GetSystemTime(&t);
+ ss << RPCLIB_FMT::format("{}-{}-{} {}:{}:{}.{:03}", t.wYear, t.wMonth,
+ t.wDay, t.wHour, t.wMinute, t.wSecond,
+ t.wMilliseconds);
+ return ss.str();
+ }
+#else
+ static std::string now() {
+ std::stringstream ss;
+ timespec now_t = {};
+ clock_gettime(CLOCK_REALTIME, &now_t);
+ ss << std::put_time(
+ std::localtime(reinterpret_cast<time_t *>(&now_t.tv_sec)),
+ "%F %T")
+ << RPCLIB_FMT::format(
+ ".{:03}", round(static_cast<double>(now_t.tv_nsec) / 1.0e6));
+ return ss.str();
+ }
+#endif
+
+ void basic_log(const char *severity, const char *channel,
+ std::string const &msg) {
+ using RPCLIB_FMT::arg;
+ std::lock_guard<std::mutex> lock(mut_print_);
+ RPCLIB_FMT::print("{time:16} {severity:6} {channel:12} {msg:40}\n",
+ arg("severity", severity), arg("channel", channel),
+ arg("time", now()), arg("msg", msg));
+ }
+
+private:
+ std::mutex mut_print_;
+};
+} /* detail */
+} /* rpc */
+
+#ifdef _MSC_VER
+#define RPCLIB_CREATE_LOG_CHANNEL(Name) \
+ static constexpr const char *rpc_channel_name = #Name;
+#elif defined(__GNUC__)
+#define RPCLIB_CREATE_LOG_CHANNEL(Name) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") \
+ static constexpr const char *rpc_channel_name = #Name; \
+ _Pragma("GCC diagnostic pop")
+#elif defined(__clang__)
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wunused-variable\"") \
+ static constexpr const char *rpc_channel_name = #Name; \
+ _Pragma("clang diagnostic pop")
+#endif
+
+RPCLIB_CREATE_LOG_CHANNEL(global)
+
+#define LOG_INFO(...) \
+ rpc::detail::logger::instance().info(rpc_channel_name, __VA_ARGS__)
+
+#define LOG_WARN(...) \
+ rpc::detail::logger::instance().warn(rpc_channel_name, __VA_ARGS__)
+
+#define LOG_ERROR(...) \
+ rpc::detail::logger::instance().error(rpc_channel_name, __VA_ARGS__)
+
+#define LOG_DEBUG(...) \
+ rpc::detail::logger::instance().debug(rpc_channel_name, __FILE__, \
+ __func__, __LINE__, __VA_ARGS__)
+
+#define LOG_TRACE(...) \
+ rpc::detail::logger::instance().trace(rpc_channel_name, __FILE__, \
+ __func__, __LINE__, __VA_ARGS__)
+
+#define LOG_EXPR(Level, Expr) LOG_##Level("`" #Expr "` = {}", Expr)
+
+#else
+
+#define LOG_INFO(...)
+#define LOG_WARN(...)
+#define LOG_ERROR(...)
+#define LOG_DEBUG(...)
+#define LOG_TRACE(...)
+#define LOG_EXPR(...)
+#define RPCLIB_CREATE_LOG_CHANNEL(...)
+
+#endif
+
+#endif /* end of include guard: LOG_H_SPSC31OG */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/make_unique.h b/host/lib/deps/rpclib/include/rpc/detail/make_unique.h
new file mode 100644
index 000000000..1297aeaab
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/make_unique.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#ifndef MAKE_UNIQUE_H_FOOBAR
+#define MAKE_UNIQUE_H_FOOBAR
+
+#include <memory>
+
+namespace rpc {
+namespace detail {
+
+// Default behaviour is to assume C++11, overriding RPCLIB_CXX_STANDARD can use
+// newer standards:
+#if RPCLIB_CXX_STANDARD >= 14
+
+using std::make_unique;
+
+#else
+
+template<typename T, typename... Ts>
+std::unique_ptr<T> make_unique(Ts&&... params)
+{
+ return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));
+}
+
+#endif
+
+} /* detail */
+} /* rpc */
+
+#endif /* end of include guard: MAKE_UNIQUE_H_FOOBAR */
+
diff --git a/host/lib/deps/rpclib/include/rpc/detail/not.h b/host/lib/deps/rpclib/include/rpc/detail/not.h
new file mode 100644
index 000000000..9d78cafb3
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/not.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#ifndef NOT_H_0MEGQWII
+#define NOT_H_0MEGQWII
+
+#include "rpc/detail/bool.h"
+
+namespace rpc {
+namespace detail {
+
+template<typename B>
+using not_ = bool_<!B::value>;
+
+}
+}
+
+#endif /* end of include guard: NOT_H_0MEGQWII */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/pimpl.h b/host/lib/deps/rpclib/include/rpc/detail/pimpl.h
new file mode 100644
index 000000000..526f788ac
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/pimpl.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#ifndef PIMPL_H_TV7E3C9K
+#define PIMPL_H_TV7E3C9K
+
+//! \brief Declares a pimpl pointer.
+#define RPCLIB_DECLARE_PIMPL() \
+ struct impl; std::unique_ptr<impl> pimpl;
+
+#endif /* end of include guard: PIMPL_H_TV7E3C9K */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/response.h b/host/lib/deps/rpclib/include/rpc/detail/response.h
new file mode 100644
index 000000000..96131b1a7
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/response.h
@@ -0,0 +1,119 @@
+#pragma once
+
+#ifndef RESPONSE_H_MVRZEKPX
+#define RESPONSE_H_MVRZEKPX
+
+#include "rpc/detail/log.h"
+#include "rpc/detail/make_unique.h"
+#include "rpc/msgpack.hpp"
+#include "rpc/config.h"
+
+namespace rpc {
+namespace detail {
+
+//! \brief Represents a response and creates a msgpack to be sent back
+//! as per the msgpack-rpc spec.
+class response {
+public:
+ //! \brief Creates a response that represents a normal return value.
+ //! \param id The sequence id (as per protocol).
+ //! \param result The return value to store in the response.
+ //! \tparam T Any msgpack-able type.
+ //! \note If there is both an error and result in the response,
+ //! the result will be discarded while packing the data.
+ template <typename T> static response make_result(uint32_t id, T &&result);
+
+ //! \brief Creates a response that represents an error.
+ //! \param id The sequence id (as per protocol).
+ //! \param error The error value to store in the response.
+ //! \tparam T Any msgpack-able type.
+ template <typename T> static response make_error(uint32_t id, T &&error);
+
+
+ //! \brief Constructs a response from RPCLIB_MSGPACK::object (useful when
+ //! reading a response from a stream).
+ response(RPCLIB_MSGPACK::object_handle o);
+
+ //! \brief Gets the response data as a RPCLIB_MSGPACK::sbuffer.
+ RPCLIB_MSGPACK::sbuffer get_data() const;
+
+ //! \brief Moves the specified object_handle into the response
+ //! as a result.
+ //! \param r The result to capture.
+ void capture_result(RPCLIB_MSGPACK::object_handle &r);
+
+ //! \brief Moves the specified object_handle into the response as an error.
+ //! \param e The error to capture.
+ void capture_error(RPCLIB_MSGPACK::object_handle &e);
+
+ //! \brief Returns the call id/index used to identify which call
+ //! this response corresponds to.
+ uint32_t get_id() const;
+
+ //! \brief Returns the error object stored in the response. Can
+ //! be empty.
+ std::shared_ptr<RPCLIB_MSGPACK::object_handle> get_error() const;
+
+ //! \brief Returns the result stored in the response. Can be empty.
+ std::shared_ptr<RPCLIB_MSGPACK::object_handle> get_result() const;
+
+ //! \brief Gets an empty response which means "no response" (not to be
+ //! confused with void return, i.e. this means literally
+ //! "don't write the response to the socket")
+ static response empty();
+
+ //! \brief If true, this response is empty (\see empty())
+ bool is_empty() const;
+
+ //! \brief The type of a response, according to the msgpack-rpc spec
+ using response_type =
+ std::tuple<uint32_t, uint32_t, RPCLIB_MSGPACK::object, RPCLIB_MSGPACK::object>;
+
+private:
+ //! \brief Default constructor for responses.
+ response();
+
+ uint32_t id_;
+ // I really wish to avoid shared_ptr here but at this point asio does not
+ // work with move-only handlers in post() and I need to capture responses
+ // in lambdas.
+ std::shared_ptr<RPCLIB_MSGPACK::object_handle> error_;
+ std::shared_ptr<RPCLIB_MSGPACK::object_handle> result_;
+ bool empty_;
+ RPCLIB_CREATE_LOG_CHANNEL(response)
+};
+
+template <typename T>
+inline response response::make_result(uint32_t id, T &&result) {
+ auto z = rpc::detail::make_unique<RPCLIB_MSGPACK::zone>();
+ RPCLIB_MSGPACK::object o(std::forward<T>(result), *z);
+ response inst;
+ inst.id_ = id;
+ inst.result_ = std::make_shared<RPCLIB_MSGPACK::object_handle>(o, std::move(z));
+ return inst;
+}
+
+template <>
+inline response
+response::make_result(uint32_t id, std::unique_ptr<RPCLIB_MSGPACK::object_handle> &&r) {
+ response inst;
+ inst.id_ = id;
+ inst.result_ = std::move(r);
+ return inst;
+}
+
+template <typename T>
+inline response response::make_error(uint32_t id, T &&error) {
+ auto z = rpc::detail::make_unique<RPCLIB_MSGPACK::zone>();
+ RPCLIB_MSGPACK::object o(std::forward<T>(error), *z);
+ response inst;
+ inst.id_ = id;
+ inst.error_ = std::make_shared<RPCLIB_MSGPACK::object_handle>(o, std::move(z));
+ return inst;
+}
+
+} /* detail */
+
+} /* rpc */
+
+#endif /* end of include guard: RESPONSE_H_MVRZEKPX */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/server_session.h b/host/lib/deps/rpclib/include/rpc/detail/server_session.h
new file mode 100644
index 000000000..963b082ec
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/server_session.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#ifndef SESSION_H_5KG6ZMAB
+#define SESSION_H_5KG6ZMAB
+
+#include <boost/asio.hpp>
+#include <memory>
+#include <vector>
+
+#include "rpc/config.h"
+#include "rpc/msgpack.hpp"
+
+#include "rpc/dispatcher.h"
+#include "rpc/detail/async_writer.h"
+#include "rpc/detail/log.h"
+
+namespace rpc {
+
+class server;
+
+namespace detail {
+
+class server_session : public async_writer {
+public:
+ server_session(server *srv, boost::asio::io_service *io,
+ boost::asio::ip::tcp::socket socket,
+ std::shared_ptr<dispatcher> disp, bool suppress_exceptions);
+ void start();
+
+ void close();
+
+private:
+ void do_read();
+
+private:
+ server* parent_;
+ boost::asio::io_service *io_;
+ boost::asio::strand read_strand_;
+ std::shared_ptr<dispatcher> disp_;
+ RPCLIB_MSGPACK::unpacker pac_;
+ RPCLIB_MSGPACK::sbuffer output_buf_;
+ const bool suppress_exceptions_;
+ RPCLIB_CREATE_LOG_CHANNEL(session)
+};
+} /* detail */
+} /* rpc */
+
+#endif /* end of include guard: SESSION_H_5KG6ZMAB */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/thread_group.h b/host/lib/deps/rpclib/include/rpc/detail/thread_group.h
new file mode 100644
index 000000000..8905a7150
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/thread_group.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#ifndef THREAD_GROUP_H_MQSLWGKD
+#define THREAD_GROUP_H_MQSLWGKD
+
+#include <thread>
+#include <vector>
+
+namespace rpc {
+namespace detail {
+
+class thread_group {
+public:
+ thread_group() {}
+ thread_group(thread_group const &) = delete;
+
+ void create_threads(std::size_t thread_count, std::function<void()> func) {
+ for (std::size_t i = 0; i < thread_count; ++i) {
+ threads_.push_back(std::thread(func));
+ }
+ }
+
+ void join_all() {
+ for (auto &t : threads_) {
+ if (t.joinable()) {
+ t.join();
+ }
+ }
+ }
+
+ ~thread_group() { join_all(); }
+
+private:
+ std::vector<std::thread> threads_;
+};
+
+} /* detail */
+} /* rpc */
+
+#endif /* end of include guard: THREAD_GROUP_H_MQSLWGKD */
diff --git a/host/lib/deps/rpclib/include/rpc/detail/util.h b/host/lib/deps/rpclib/include/rpc/detail/util.h
new file mode 100644
index 000000000..302cb93b7
--- /dev/null
+++ b/host/lib/deps/rpclib/include/rpc/detail/util.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#ifndef UTIL_H_YRIZ63UJ
+#define UTIL_H_YRIZ63UJ
+
+#include "rpc/msgpack.hpp"
+#include "rpc/detail/make_unique.h"
+
+namespace rpc {
+namespace detail {
+template <typename T> RPCLIB_MSGPACK::object_handle pack(T &&o) {
+ auto z = rpc::detail::make_unique<RPCLIB_MSGPACK::zone>();
+ RPCLIB_MSGPACK::object obj(std::forward<T>(o), *z);
+ return RPCLIB_MSGPACK::object_handle(obj, std::move(z));
+}
+} /* detail */
+} /* rpc */
+
+#endif /* end of include guard: UTIL_H_YRIZ63UJ */