diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2016-01-20 05:35:09 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2016-01-20 05:35:09 +0300 |
commit | 09a905e401df451f12673d75dc8d4d72ee73b7c9 (patch) | |
tree | 75e620ca41dd673f9286f3351f2982c2bbfc51e1 | |
parent | bb8cd8a9ff7d80046cc2c7d41742c74d8f811c62 (diff) |
server:
very basic implementation of download_state_changed event api call for plugins
started work on thread safety (plugins may and will be multithreaded, so api for plugins should be thread safe)
-rw-r--r-- | server/include/api_core_events.h | 11 | ||||
-rw-r--r-- | server/include/utilities.h | 16 | ||||
-rw-r--r-- | server/src/api_core_events.cpp | 47 | ||||
-rw-r--r-- | server/src/main.cpp | 6 | ||||
-rw-r--r-- | server/src/server.cpp | 6 | ||||
-rw-r--r-- | server/src/server_session.cpp | 2 |
6 files changed, 80 insertions, 8 deletions
diff --git a/server/include/api_core_events.h b/server/include/api_core_events.h index e7e0dac..072ec45 100644 --- a/server/include/api_core_events.h +++ b/server/include/api_core_events.h @@ -21,15 +21,24 @@ #ifndef API_CORE_EVENTS_H #define API_CORE_EVENTS_H +class module_base; + namespace core_events { enum download_state {download_stopped, download_running, download_completed, download_error}; +struct download_state_info +{ + int download_id; + download_state state; +}; + + class core_events { public: - virtual void download_state_changed(int download_id, download_state state); + virtual void download_state_changed(module_base *m, std::list<download_state_info> state_list); }; }; diff --git a/server/include/utilities.h b/server/include/utilities.h index 40eb38f..3e77f89 100644 --- a/server/include/utilities.h +++ b/server/include/utilities.h @@ -25,6 +25,7 @@ #include <string> #include <memory> + //TODO: use glib's xdg api instead ? std::string replace_home_var(const std::string &path); @@ -35,6 +36,21 @@ std::shared_ptr<char*> pack_msg(server_msg *msg, int *size); std::string random_string(int length); std::string generate_auth_token(); +#include <boost/thread/lockable_adapter.hpp> +#include <boost/thread/mutex.hpp> + +template <typename CONTAINER> +class lockable_container : public boost::basic_lockable_adapter<boost::mutex>, public CONTAINER +{ + +}; + +/*template <typename CONTAINER> +class lockable_container_child : public lockable_container <CONTAINER> +{ + //code +}; */ + #endif // UTILITIES_H_INCLUDED diff --git a/server/src/api_core_events.cpp b/server/src/api_core_events.cpp index 0259973..525f60b 100644 --- a/server/src/api_core_events.cpp +++ b/server/src/api_core_events.cpp @@ -23,14 +23,57 @@ #include "api_core_events.h" #include "server_session.h" +#include "utilities.h" +#include "../../protocol/udm.pb.h" +#include "api_module_base.h" +#include <boost/log/trivial.hpp> -extern std::list<server_session*> sessions; +extern lockable_container<std::list<server_session*> > sessions; +extern lockable_container<std::map<int, download_internal_s> > downloads; namespace core_events { -void core_events::download_state_changed(int download_id, download_state state) +void core_events::download_state_changed(module_base *m, std::list<download_state_info> state_list) //TODO: multiple downloads at once should be supported { + //TODO: redesign, very unefficient implementation (reverse search in downloads list should be eleminated) + server_msg msg; + msg.set_type(SERVER_MSG_TYPE::SERVER_DOWNLOAD_STATE_CHANGE); + downloads.lock(); + for(auto s : state_list) + { + for(auto d : downloads) + { + if(d.second.module_name == m->get_module_info().name) + { + if(s.download_id == d.second.module_id) + { + download_state_change *sc =msg.add_download_state_changes(); + sc->set_download_id(d.first); + switch(s.state) + { + case download_state::download_stopped: + sc->set_state(SUBSCRIPTION_DOWNLOAD_STATE::SDS_STOPPED); + break; + case download_state::download_running: + sc->set_state(SUBSCRIPTION_DOWNLOAD_STATE::SDS_STARTED); + break; + default: + BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__<<"\nunhandled download state change event"; + break; + + } + } + } + } + } + downloads.unlock(); + sessions.lock(); + for(auto p : sessions) + { + p->fire_event(SUBSCRIPTION_TYPE::ST_DOWNLOAD_STATE_CHANGE, msg); + } + sessions.unlock(); } }; diff --git a/server/src/main.cpp b/server/src/main.cpp index 47dba02..b45ce8f 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -41,13 +41,13 @@ modules_handler *modules = nullptr; namespace bpo = boost::program_options; -std::map<std::string, client*> clients; //auth token used for key +lockable_container<std::map<std::string, client*> > clients; //auth token used for key runtime_config_s runtime_config; -std::map<int, download_internal_s> downloads; +lockable_container<std::map<int, download_internal_s> > downloads; -std::list<server_session*> sessions; //sessions to access from apis for modules, should be mutex guarded fro thread safety +lockable_container<std::list<server_session*> > sessions; //sessions to access from apis for modules, should be mutex guarded fro thread safety server *serv = nullptr; diff --git a/server/src/server.cpp b/server/src/server.cpp index 3c769d3..ef60cf4 100644 --- a/server/src/server.cpp +++ b/server/src/server.cpp @@ -28,7 +28,7 @@ #include "../../protocol/udm.pb.h" #include "socket_wraper.h" -extern std::list<server_session*> sessions; +extern lockable_container<std::list<server_session*> > sessions; @@ -51,7 +51,9 @@ server::server(boost::asio::io_service& io_service,runtime_config_s &config, std void server::start_accept() { server_session* new_session = new server_session(io_service_, runtime_config, clients, downloads); + sessions.lock(); sessions.push_back(new_session); + sessions.unlock(); if(runtime_config.config_file.get<bool>("server.enable_encryption", false)) acceptor_.async_accept(new_session->socket()->get_ssl_socket().lowest_layer(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); else @@ -67,9 +69,11 @@ void server::handle_accept(server_session* new_session, const boost::system::err else { //TODO: implement thread safety ? + sessions.lock(); auto s = std::find(sessions.begin(), sessions.end(), new_session); if(s != sessions.end()) sessions.erase(s); + sessions.unlock(); delete new_session; } start_accept(); diff --git a/server/src/server_session.cpp b/server/src/server_session.cpp index 5a15e5b..bfab451 100644 --- a/server/src/server_session.cpp +++ b/server/src/server_session.cpp @@ -30,7 +30,7 @@ #include "event_subscription_event.h" #include "event_subscription_repeated.h" -extern std::map<std::string, client> clients; +extern lockable_container<std::map<std::string, client*> > clients; extern modules_handler *modules; |