source: nscp/service/channels.hpp @ 1ecd26f

0.4.00.4.10.4.2
Last change on this file since 1ecd26f was 1ecd26f, checked in by Michael Medin <michael@…>, 2 years ago

syncronized streams between 0.4.x and 0.3.x as well as improed the CMAke build *alot*

  • Property mode set to 100644
File size: 4.4 KB
Line 
1#pragma once
2
3#include <set>
4
5#include <boost/shared_ptr.hpp>
6#include <boost/foreach.hpp>
7
8#include "NSCPlugin.h"
9#include "logger.hpp"
10
11using namespace nscp::helpers;
12
13namespace nsclient {
14        class channels : boost::noncopyable {
15        public:
16                class channel_exception : public std::exception {
17                        std::string what_;
18                public:
19                        channel_exception(std::wstring error) throw() : what_(to_string(error).c_str()) {}
20                        channel_exception(std::string error) throw() : what_(error.c_str()) {}
21                        virtual ~channel_exception() throw() {};
22
23                        virtual const char* what() const throw() {
24                                return what_.c_str();
25                        }
26
27                };
28
29                typedef boost::shared_ptr<NSCPlugin> plugin_type;
30                typedef std::map<unsigned long,plugin_type> plugin_list_type;
31                typedef std::set<unsigned long> plugin_id_type;
32                typedef std::map<std::wstring,plugin_id_type > channel_list_type;
33
34
35        private:
36                nsclient::logger *logger_;
37                plugin_list_type plugins_;
38                channel_list_type channels_;
39                boost::shared_mutex mutex_;
40
41        public:
42
43                channels(nsclient::logger *logger) : logger_(logger) {}
44
45                void add_plugin(plugin_type plugin) {
46                        if (!plugin || !plugin->hasNotificationHandler())
47                                return;
48                        plugins_[plugin->get_id()] = plugin;
49                       
50                }
51
52                void remove_all() {
53                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(30));
54                        if (!writeLock.owns_lock()) {
55                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: channels::remove_all"));
56                                return;
57                        }
58                        channels_.clear();
59                        plugins_.clear();
60                }
61
62                void remove_plugin(unsigned long id) {
63                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(10));
64                        if (!writeLock.owns_lock()) {
65                                log_error(__FILE__, __LINE__, _T("Failed to get mutex in remove_plugin for plugin id: ") + ::to_wstring(id));
66                                return;
67                        }
68                        channel_list_type::iterator it = channels_.begin();
69                        while (it != channels_.end()) {
70                                if ((*it).second.count(id) > 0) {
71                                        channel_list_type::iterator toerase = it;
72                                        ++it;
73                                        channels_.erase(toerase);
74                                } else
75                                        ++it;
76                        }
77                        plugin_list_type::iterator pit = plugins_.find(id);
78                        if (pit != plugins_.end())
79                                plugins_.erase(pit);
80                }
81
82                void register_listener(unsigned long plugin_id, std::wstring channel) {
83                        boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(10));
84                        if (!writeLock.owns_lock()) {
85                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + channel);
86                                return;
87                        }
88                        std::wstring lc = make_key(channel);
89                        if (!have_plugin(plugin_id))
90                                throw channel_exception("Failed to find plugin: " + ::to_string(plugin_id));
91                        channels_[lc].insert(plugin_id);
92                }
93
94                std::list<std::wstring> list() {
95                        std::list<std::wstring> lst;
96                        boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5));
97                        if (!readLock.owns_lock()) {
98                                log_error(__FILE__, __LINE__, _T("Failed to get mutex"));
99                                return lst;
100                        }
101                       
102                        BOOST_FOREACH(channel_list_type::value_type i, channels_) {
103                                lst.push_back(i.first);
104                        }
105                        return lst;
106                }
107
108                std::list<plugin_type> get(std::wstring channel) {
109                        boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5));
110                        if (!readLock.owns_lock()) {
111                                log_error(__FILE__, __LINE__, _T("Failed to get mutex: ") + channel);
112                                throw channel_exception("Failed to get mutex (channel::get)");
113                        }
114                        std::wstring lc = make_key(channel);
115                        channel_list_type::iterator cit = channels_.find(lc);
116                        if (cit == channels_.end()) {
117                                throw channel_exception("Channel not found: " + to_string(channel));
118                        }
119                        std::list<plugin_type> ret;
120                        BOOST_FOREACH(unsigned long id, cit->second) {
121                                ret.push_back(plugins_[id]);
122                        }
123                        return ret;
124                }
125
126                std::wstring to_wstring() {
127                        std::wstring ret;
128                        BOOST_FOREACH(std::wstring str, list()) {
129                                if (!ret.empty()) ret += _T(", ");
130                                ret += str;
131                        }
132                        return ret;
133                }
134
135                inline std::wstring make_key(std::wstring key) {
136                        return boost::algorithm::to_lower_copy(key);
137                }
138                void log_error(std::string file, int line, std::wstring error) {
139                        if (logger_ != NULL)
140                                logger_->nsclient_log_error(file, line, error);
141                }
142
143                inline bool have_plugin(unsigned long plugin_id) {
144                        return !(plugins_.find(plugin_id) == plugins_.end());
145                }
146        };
147}
Note: See TracBrowser for help on using the repository browser.