diff options
author | Andrej Rode <andrej.rode@ettus.com> | 2017-04-03 18:49:58 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:45 -0800 |
commit | 53795c74aead4e6021bc788b788f8ed5b4a0166d (patch) | |
tree | 45e4075f3d8ffdee7dff7c72dd665f5c5b0c746c /host/lib/deps/rpclib/include/rpc/dispatcher.h | |
parent | 6a12add1560545438e1bebc05efbafd05aace4f9 (diff) | |
download | uhd-53795c74aead4e6021bc788b788f8ed5b4a0166d.tar.gz uhd-53795c74aead4e6021bc788b788f8ed5b4a0166d.tar.bz2 uhd-53795c74aead4e6021bc788b788f8ed5b4a0166d.zip |
uhd: add cut-down rpclib source tree and import tool
Diffstat (limited to 'host/lib/deps/rpclib/include/rpc/dispatcher.h')
-rw-r--r-- | host/lib/deps/rpclib/include/rpc/dispatcher.h | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/host/lib/deps/rpclib/include/rpc/dispatcher.h b/host/lib/deps/rpclib/include/rpc/dispatcher.h new file mode 100644 index 000000000..513fae686 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/dispatcher.h @@ -0,0 +1,122 @@ +#pragma once + +#ifndef DISPATCHER_H_CXIVZD5L +#define DISPATCHER_H_CXIVZD5L + +#include <atomic> +#include <functional> +#include <memory> +#include <unordered_map> + +#include "rpc/config.h" +#include "rpc/msgpack.hpp" + +#include "rpc/detail/call.h" +#include "rpc/detail/func_tools.h" +#include "rpc/detail/func_traits.h" +#include "rpc/detail/log.h" +#include "rpc/detail/not.h" +#include "rpc/detail/response.h" +#include "rpc/detail/make_unique.h" + +namespace rpc { + +namespace detail { + +//! \brief This class maintains a registry of functors associated with their +//! names, and callable using a msgpack-rpc call pack. +class dispatcher { +public: + //! \brief Binds a functor to a name so it becomes callable via RPC. + //! \param name The name of the functor. + //! \param func The functor to bind. + //! \tparam F The type of the functor. + template <typename F> void bind(std::string const &name, F func); + + //! \defgroup Tag-dispatched bind implementations for various functor cases. + //! @{ + + //! \brief Stores a void, zero-arg functor with a name. + template <typename F> + void bind(std::string const &name, F func, + detail::tags::void_result const &, + detail::tags::zero_arg const &); + + //! \brief Stores a void, non-zero-arg functor with a name. + template <typename F> + void bind(std::string const &name, F func, + detail::tags::void_result const &, + detail::tags::nonzero_arg const &); + + //! \brief Stores a non-void, zero-arg functor with a name. + template <typename F> + void bind(std::string const &name, F func, + detail::tags::nonvoid_result const &, + detail::tags::zero_arg const &); + + //! \brief Stores a non-void, non-zero-arg functor with a name. + template <typename F> + void bind(std::string const &name, F func, + detail::tags::nonvoid_result const &, + detail::tags::nonzero_arg const &); + + //! @} + + //! \brief Processes a message that contains a call according to + //! the Msgpack-RPC spec. + //! \param msg The buffer that contains the messagepack. + //! \throws std::runtime_error If the messagepack does not contain a + //! a call or the types of the parameters are not convertible to the called + //! functions' parameters. + void dispatch(RPCLIB_MSGPACK::sbuffer const &msg); + + //! \brief Processes a message that contains a call according to + //! the Msgpack-RPC spec. + //! \param msg The messagepack object that contains the call. + //! \param suppress_exceptions If true, exceptions will be caught and + //! written + //! as response for the client. + //! \throws std::runtime_error If the types of the parameters are not + //! convertible to the called functions' parameters. + detail::response dispatch(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions = false); + + //! \brief This functor type unifies the interfaces of functions that are + //! called remotely + using adaptor_type = std::function<std::unique_ptr<RPCLIB_MSGPACK::object_handle>( + RPCLIB_MSGPACK::object const &)>; + + //! \brief This is the type of messages as per the msgpack-rpc spec. + using call_t = std::tuple<int8_t, uint32_t, std::string, RPCLIB_MSGPACK::object>; + + //! \brief This is the type of notification messages. + using notification_t = std::tuple<int8_t, std::string, RPCLIB_MSGPACK::object>; + +private: + //! \brief Checks the argument count and throws an exception if + //! it is not the expected amount. + static void enforce_arg_count(std::string const &func, std::size_t found, + std::size_t expected); + + //! \brief Dispatches a call (which will have a response). + detail::response dispatch_call(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions = false); + + //! \brief Dispatches a notification (which will not have a response) + detail::response dispatch_notification(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions = false); + + template <typename T> RPCLIB_MSGPACK::object pack(T &&arg); + + enum class request_type { call = 0, notification = 2 }; + +private: + std::unordered_map<std::string, adaptor_type> funcs_; + RPCLIB_CREATE_LOG_CHANNEL(dispatcher) +}; +} +} + +#include "dispatcher.inl" + +#endif /* end of include guard: DISPATCHER_H_CXIVZD5L */ |