diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index 57c9475f516496bdcab197e0f3936fb5bf4a2a9f..e668d1ee1f705c11880cbc5dbe127a61b3e69ef9 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -34,6 +34,7 @@ std::string object_type_to_string(const msgpack::type::object_type t) { } vector<string> Dispatcher::getBindings() const { + SHARED_LOCK(mutex_, lk); vector<string> res; for (auto x : funcs_) { res.push_back(x.first); @@ -94,6 +95,7 @@ void ftl::net::Dispatcher::dispatch_call(Peer &s, const msgpack::object &msg) { } optional<Dispatcher::adaptor_type> ftl::net::Dispatcher::_locateHandler(const std::string &name) const { + SHARED_LOCK(mutex_, lk); auto it_func = funcs_.find(name); if (it_func == funcs_.end()) { if (parent_ != nullptr) { @@ -107,6 +109,7 @@ optional<Dispatcher::adaptor_type> ftl::net::Dispatcher::_locateHandler(const st } bool ftl::net::Dispatcher::isBound(const std::string &name) const { + SHARED_LOCK(mutex_, lk); return funcs_.find(name) != funcs_.end(); } @@ -151,6 +154,7 @@ void ftl::net::Dispatcher::enforce_arg_count(std::string const &func, std::size_ } void ftl::net::Dispatcher::enforce_unique_name(std::string const &func) { + SHARED_LOCK(mutex_, lk); auto pos = funcs_.find(func); if (pos != end(funcs_)) { throw FTL_Error("RPC non unique binding for '" << func << "'"); diff --git a/src/dispatcher.hpp b/src/dispatcher.hpp index c7f89274ff364e40a59aaefe2ec99cd899afc2a8..333c77de26a0906b5bd6cb0d965f07325e56bbab 100644 --- a/src/dispatcher.hpp +++ b/src/dispatcher.hpp @@ -18,6 +18,8 @@ #include "func_traits.hpp" +#include <ftl/threads.hpp> + #include <msgpack.hpp> namespace ftl { @@ -70,10 +72,7 @@ namespace net { */ class Dispatcher { public: - explicit Dispatcher(Dispatcher *parent = nullptr) : parent_(parent) { - // FIXME: threading and funcs_; hack use large size - funcs_.reserve(1024); - } + explicit Dispatcher(Dispatcher *parent = nullptr) : parent_(parent) {} /** * Primary method by which a peer dispatches a msgpack object that this @@ -94,6 +93,7 @@ class Dispatcher { ftl::internal::tags::zero_arg const &, ftl::internal::false_ const &) { enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert( std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { enforce_arg_count(name, 0, args.via.array.size); @@ -116,6 +116,7 @@ class Dispatcher { using args_type = typename func_traits<F>::args_type; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert( std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { constexpr int args_count = std::tuple_size<args_type>::value; @@ -140,6 +141,7 @@ class Dispatcher { using ftl::internal::func_traits; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert(std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { enforce_arg_count(name, 0, args.via.array.size); @@ -163,6 +165,7 @@ class Dispatcher { using args_type = typename func_traits<F>::args_type; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert(std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { constexpr int args_count = std::tuple_size<args_type>::value; @@ -183,6 +186,7 @@ class Dispatcher { ftl::internal::tags::zero_arg const &, ftl::internal::true_ const &) { enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert( std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { enforce_arg_count(name, 0, args.via.array.size); @@ -200,6 +204,7 @@ class Dispatcher { using args_type = typename func_traits<F>::args_type; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert( std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { constexpr int args_count = std::tuple_size<args_type>::value; @@ -219,6 +224,7 @@ class Dispatcher { using ftl::internal::func_traits; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert(std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { enforce_arg_count(name, 0, args.via.array.size); @@ -237,6 +243,7 @@ class Dispatcher { using args_type = typename func_traits<F>::args_type; enforce_unique_name(name); + UNIQUE_LOCK(mutex_, lk); funcs_.insert(std::make_pair(name, [func, name](ftl::net::Peer &p, msgpack::object const &args) { constexpr int args_count = std::tuple_size<args_type>::value; @@ -255,6 +262,7 @@ class Dispatcher { * Remove a previous bound function by name. */ void unbind(const std::string &name) { + UNIQUE_LOCK(mutex_, lk); auto i = funcs_.find(name); if (i != funcs_.end()) { funcs_.erase(i); @@ -290,6 +298,7 @@ class Dispatcher { private: Dispatcher *parent_; std::unordered_map<std::string, adaptor_type> funcs_; + mutable SHARED_MUTEX mutex_; std::optional<adaptor_type> _locateHandler(const std::string &name) const;