summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2016-01-20 05:35:09 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2016-01-20 05:35:09 +0300
commit09a905e401df451f12673d75dc8d4d72ee73b7c9 (patch)
tree75e620ca41dd673f9286f3351f2982c2bbfc51e1
parentbb8cd8a9ff7d80046cc2c7d41742c74d8f811c62 (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.h11
-rw-r--r--server/include/utilities.h16
-rw-r--r--server/src/api_core_events.cpp47
-rw-r--r--server/src/main.cpp6
-rw-r--r--server/src/server.cpp6
-rw-r--r--server/src/server_session.cpp2
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;