Fawkes API Fawkes Development Version
manager.cpp
1
2/***************************************************************************
3 * manager.cpp - Fawkes plugin manager
4 *
5 * Created: Wed Nov 15 23:31:55 2006 (on train to Cologne)
6 * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <config/config.h>
25#include <core/exception.h>
26#include <core/plugin.h>
27#include <core/threading/mutex_locker.h>
28#include <core/threading/thread_collector.h>
29#include <core/threading/thread_initializer.h>
30#include <logging/liblogger.h>
31#include <plugin/listener.h>
32#include <plugin/loader.h>
33#include <plugin/manager.h>
34#include <sys/types.h>
35#include <utils/misc/string_split.h>
36#include <utils/system/dynamic_module/module_manager.h>
37#include <utils/system/fam_thread.h>
38
39#include <algorithm>
40#include <cerrno>
41#include <cstdlib>
42#include <cstring>
43#include <dirent.h>
44
45namespace fawkes {
46
47/// @cond INTERNALS
48class plname_eq
49{
50public:
51 plname_eq(std::string name)
52 {
53 name_ = name;
54 }
55 bool
56 operator()(Plugin *plugin)
57 {
58 return (name_ == plugin->name());
59 }
60
61private:
62 std::string name_;
63};
64/// @endcond INTERNALS
65
66/** @class PluginManager <plugin/manager.h>
67 * Fawkes Plugin Manager.
68 * This class provides a manager for the plugins used in fawkes. It can
69 * load and unload modules.
70 *
71 * @author Tim Niemueller
72 */
73
74/** Constructor.
75 * @param thread_collector thread manager plugin threads will be added to
76 * and removed from appropriately.
77 * @param config Fawkes configuration
78 * @param meta_plugin_prefix Path prefix for meta plugins
79 * @param module_flags flags to use to open plugin modules
80 * @param init_cache true to initialize the plugin cache, false to skip this
81 * step. Note that some functions like transmitting a list of available plugins
82 * is unavailable until the cache has been initialized. You can defer
83 * initialization of the cache if required.
84 */
86 Configuration * config,
87 const char * meta_plugin_prefix,
88 Module::ModuleFlags module_flags,
89 bool init_cache)
90: ConfigurationChangeHandler(meta_plugin_prefix)
91{
92 mutex_ = new Mutex();
93 this->thread_collector = thread_collector;
94 plugin_loader = new PluginLoader(PLUGINDIR, config);
95 plugin_loader->get_module_manager()->set_open_flags(module_flags);
96 next_plugin_id = 1;
97 config_ = config;
98 meta_plugin_prefix_ = meta_plugin_prefix;
99
100 if (init_cache) {
102 }
103
104 config_->add_change_handler(this);
105
106 fam_thread_ = new FamThread();
107#ifdef HAVE_INOTIFY
108 RefPtr<FileAlterationMonitor> fam = fam_thread_->get_fam();
109 fam->add_filter("^[^.].*\\." SOEXT "$");
110 fam->add_listener(this);
111 fam->watch_dir(PLUGINDIR);
112 fam_thread_->start();
113#else
114 LibLogger::log_warn("PluginManager",
115 "File alteration monitoring not available, "
116 "cannot detect changed plugins on disk.");
117#endif
118}
119
120/** Destructor. */
122{
123#ifdef HAVE_INOTIFY
124 fam_thread_->cancel();
125 fam_thread_->join();
126#endif
127 delete fam_thread_;
128 config_->rem_change_handler(this);
129 pinfo_cache_.lock();
130 pinfo_cache_.clear();
131 pinfo_cache_.unlock();
132 // Unload all plugins
133 for (rpit = plugins.rbegin(); rpit != plugins.rend(); ++rpit) {
134 try {
135 thread_collector->force_remove((*rpit)->threads());
136 } catch (Exception &e) {
137 // We want it to be quiet on destruction, i.e. Fawkes quitting
138 //LibLogger::log_warn("PluginManager", "Forced unloading of %s caused exception",
139 // (*rpit)->name());
140 //LibLogger::log_warn("PluginManager", e);
141 }
142 plugin_loader->unload(*rpit);
143 }
144 plugins.clear();
145 plugin_ids.clear();
146 delete plugin_loader;
147 delete mutex_;
148}
149
150/** Set flags to open modules with.
151 * @param flags flags to pass to modules when opening them
152 */
153void
155{
156 plugin_loader->get_module_manager()->set_open_flags(flags);
157}
158
159/** Initialize plugin info cache. */
160void
162{
163 pinfo_cache_.lock();
164
165 DIR * plugin_dir;
166 struct dirent *dirp;
167 const char * file_ext = "." SOEXT;
168
169 if (NULL == (plugin_dir = opendir(PLUGINDIR))) {
170 throw Exception(errno, "Plugin directory %s could not be opened", PLUGINDIR);
171 }
172
173 for (unsigned int i = 0; NULL != (dirp = readdir(plugin_dir)); ++i) {
174 char * file_name = dirp->d_name;
175 char * pos = strstr(file_name, file_ext);
176 std::string plugin_name =
177 std::string(file_name).substr(0, strlen(file_name) - strlen(file_ext));
178 if (NULL != pos) {
179 try {
180 pinfo_cache_.push_back(
181 make_pair(plugin_name, plugin_loader->get_description(plugin_name.c_str())));
182 } catch (Exception &e) {
183 LibLogger::log_warn("PluginManager",
184 "Could not get description of plugin %s, "
185 "exception follows",
186 plugin_name.c_str());
187 LibLogger::log_warn("PluginManager", e);
188 }
189 }
190 }
191
192 closedir(plugin_dir);
193
194 try {
195 Configuration::ValueIterator *i = config_->search(meta_plugin_prefix_.c_str());
196 while (i->next()) {
197 if (i->is_string()) {
198 std::string p = std::string(i->path()).substr(meta_plugin_prefix_.length());
199 std::string s = std::string("Meta: ") + i->get_string();
200
201 pinfo_cache_.push_back(make_pair(p, s));
202 }
203 }
204 delete i;
205 } catch (Exception &e) {
206 }
207
208 pinfo_cache_.sort();
209 pinfo_cache_.unlock();
210}
211
212/** Generate list of all available plugins.
213 * @return list of plugins that are available, each plugin is represented by
214 * a pair of strings. The first string is the plugin name, the second is its
215 * description.
216 */
217std::list<std::pair<std::string, std::string>>
219{
220 std::list<std::pair<std::string, std::string>> rv;
221
222 std::list<std::pair<std::string, std::string>>::iterator i;
223 for (i = pinfo_cache_.begin(); i != pinfo_cache_.end(); ++i) {
224 rv.push_back(*i);
225 }
226
227 return rv;
228}
229
230/** Get list of loaded plugins.
231 * @return list of names of real and meta plugins currently loaded
232 */
233std::list<std::string>
235{
236 std::list<std::string> rv;
237
238 plugins.lock();
239 for (pit = plugins.begin(); pit != plugins.end(); ++pit) {
240 rv.push_back((*pit)->name());
241 }
242 plugins.unlock();
243 meta_plugins_.lock();
244 for (mpit_ = meta_plugins_.begin(); mpit_ != meta_plugins_.end(); ++mpit_) {
245 rv.push_back(mpit_->first);
246 }
247 meta_plugins_.unlock();
248
249 return rv;
250}
251
252/** Check if plugin is loaded.
253 * @param plugin_name plugin to check if it is loaded
254 * @return true if the plugin is currently loaded, false otherwise
255 */
256bool
257PluginManager::is_loaded(const std::string &plugin_name)
258{
259 if (plugin_loader->is_loaded(plugin_name.c_str())) {
260 return true;
261 } else {
262 // Could still be a meta plugin
263 return (meta_plugins_.find(plugin_name) != meta_plugins_.end());
264 }
265}
266
267/** Check if plugin is a meta plugin.
268 * @param plugin_name plugin to check
269 * @return true if the plugin is a meta plugin, false otherwise
270 */
271bool
272PluginManager::is_meta_plugin(const std::string &plugin_name)
273{
274 try {
275 std::string meta_plugin_path = meta_plugin_prefix_ + plugin_name;
276 return (config_->is_string(meta_plugin_path.c_str()));
277 } catch (ConfigEntryNotFoundException &e) {
278 return false;
279 }
280}
281
282/** Get meta plugin children.
283 * @param plugin_name plugin to check
284 * @return List of plugins which would be loaded for this plugin.
285 */
286std::list<std::string>
287PluginManager::get_meta_plugin_children(const std::string &plugin_name)
288{
289 std::string meta_plugin_path = meta_plugin_prefix_ + plugin_name;
290 std::string meta_plugin_str = config_->get_string(meta_plugin_path.c_str());
291 return parse_plugin_list(meta_plugin_str.c_str());
292}
293
294/** Parse a list of plugin types.
295 * Takes a comma-separated list of plugins and parses them into the individual
296 * plugin names.
297 * @param plugin_type_list string containing a comma-separated list of plugin types
298 * @return parsed list of plugin types
299 */
300std::list<std::string>
301PluginManager::parse_plugin_list(const char *plugin_list)
302{
303 std::list<std::string> rv;
304
305 char *plugins = strdup(plugin_list);
306 char *saveptr;
307 char *plugin;
308
309 plugin = strtok_r(plugins, ",", &saveptr);
310 while (plugin) {
311 rv.push_back(plugin);
312 plugin = strtok_r(NULL, ",", &saveptr);
313 }
314 free(plugins);
315
316 return rv;
317}
318
319/** Load plugin.
320 * The loading is interrupted if any of the plugins does not load properly.
321 * The already loaded plugins are *not* unloaded, but kept.
322 * @param plugin_list list of plugin names to load. The plugin list can contain meta plugins.
323 */
324void
325PluginManager::load(const std::string &plugin_list)
326{
327 load(parse_plugin_list(plugin_list.c_str()));
328}
329
330/** Load plugin.
331 * The loading is interrupted if any of the plugins does not load properly.
332 * The already loaded plugins are *not* unloaded, but kept.
333 * @param plugin_list string containing a comma-separated list of plugins
334 * to load. The plugin list can contain meta plugins.
335 */
336void
337PluginManager::load(const std::list<std::string> &plugin_list)
338{
339 for (std::list<std::string>::const_iterator i = plugin_list.begin(); i != plugin_list.end();
340 ++i) {
341 if (i->length() == 0)
342 continue;
343
344 bool try_real_plugin = true;
345 if (meta_plugins_.find(*i) == meta_plugins_.end()) {
346 std::string meta_plugin = meta_plugin_prefix_ + *i;
347 bool found_meta = false;
348 std::list<std::string> pset;
349 try {
350 if (config_->is_list(meta_plugin.c_str())) {
351 std::vector<std::string> tmp = config_->get_strings(meta_plugin.c_str());
352 pset.insert(pset.end(), tmp.begin(), tmp.end());
353 } else
354 pset = parse_plugin_list(config_->get_string(meta_plugin.c_str()).c_str());
355 found_meta = true;
356 } catch (ConfigEntryNotFoundException &e) {
357 // no meta plugin defined by that name
358 //printf("No meta plugin defined with the name %s\n", i->c_str());
359 try_real_plugin = true;
360 }
361
362 if (found_meta) {
363 if (pset.size() == 0) {
364 throw Exception("Refusing to load an empty meta plugin");
365 }
366 //printf("Going to load meta plugin %s (%s)\n", i->c_str(), pset.c_str());
367 meta_plugins_.lock();
368 // Setting has to happen here, so that a meta plugin will not cause an
369 // endless loop if it references itself!
370 meta_plugins_[*i] = pset;
371 meta_plugins_.unlock();
372 try {
373 LibLogger::log_info("PluginManager",
374 "Loading plugins %s for meta plugin %s",
375 str_join(pset.begin(), pset.end(), ",").c_str(),
376 i->c_str());
377 load(pset);
378 LibLogger::log_debug("PluginManager", "Loaded meta plugin %s", i->c_str());
379 notify_loaded(i->c_str());
380 } catch (Exception &e) {
381 e.append("Could not initialize meta plugin %s, aborting loading.", i->c_str());
382 meta_plugins_.erase_locked(*i);
383 throw;
384 }
385
386 try_real_plugin = false;
387 }
388 }
389
390 if (try_real_plugin
391 && (find_if(plugins.begin(), plugins.end(), plname_eq(*i)) == plugins.end())) {
392 try {
393 //printf("Going to load real plugin %s\n", i->c_str());
394 Plugin *plugin = plugin_loader->load(i->c_str());
395 plugins.lock();
396 try {
397 thread_collector->add(plugin->threads());
398 plugins.push_back(plugin);
399 plugin_ids[*i] = next_plugin_id++;
400 LibLogger::log_debug("PluginManager", "Loaded plugin %s", i->c_str());
401 notify_loaded(i->c_str());
403 e.append("Plugin >>> %s <<< could not be initialized, unloading", i->c_str());
404 plugins.unlock();
405 plugin_loader->unload(plugin);
406 throw;
407 }
408 plugins.unlock();
409 } catch (Exception &e) {
410 MutexLocker lock(meta_plugins_.mutex());
411 if (meta_plugins_.find(*i) == meta_plugins_.end()) {
412 // only throw exception if no meta plugin with that name has
413 // already been loaded
414 throw;
415 }
416 }
417 }
418 }
419}
420
421/** Unload plugin.
422 * Note that this method does not allow to pass a list of plugins, but it will
423 * only accept a single plugin at a time.
424 * @param plugin_name plugin to unload, can be a meta plugin.
425 */
426void
427PluginManager::unload(const std::string &plugin_name)
428{
429 MutexLocker lock(plugins.mutex());
430 if ((pit = find_if(plugins.begin(), plugins.end(), plname_eq(plugin_name))) != plugins.end()) {
431 try {
432 thread_collector->remove((*pit)->threads());
433 plugin_loader->unload(*pit);
434 plugins.erase(pit);
435 plugin_ids.erase(plugin_name);
436 notify_unloaded(plugin_name.c_str());
437 // find all meta plugins that required this module, this can no longer
438 // be considered loaded
439 meta_plugins_.lock();
440 mpit_ = meta_plugins_.begin();
441 while (mpit_ != meta_plugins_.end()) {
442 std::list<std::string> pp = mpit_->second;
443
444 bool erase = false;
445 for (std::list<std::string>::iterator i = pp.begin(); i != pp.end(); ++i) {
446 if (*i == plugin_name) {
447 erase = true;
448 break;
449 }
450 }
451 if (erase) {
452 LockMap<std::string, std::list<std::string>>::iterator tmp = mpit_;
453 ++mpit_;
454 notify_unloaded(tmp->first.c_str());
455 meta_plugins_.erase(tmp);
456 } else {
457 ++mpit_;
458 }
459 }
460 meta_plugins_.unlock();
461
462 } catch (Exception &e) {
463 LibLogger::log_error("PluginManager",
464 "Could not finalize one or more threads "
465 "of plugin %s, NOT unloading plugin",
466 plugin_name.c_str());
467 throw;
468 }
469 } else if (meta_plugins_.find(plugin_name) != meta_plugins_.end()) {
470 std::list<std::string> pp = meta_plugins_[plugin_name];
471
472 for (std::list<std::string>::reverse_iterator i = pp.rbegin(); i != pp.rend(); ++i) {
473 if (i->length() == 0)
474 continue;
475 if ((find_if(plugins.begin(), plugins.end(), plname_eq(*i)) == plugins.end())
476 && (meta_plugins_.find(*i) != meta_plugins_.end())) {
477 continue;
478 }
479
480 meta_plugins_.erase_locked(*i);
481 LibLogger::log_info("PluginManager",
482 "UNloading plugin %s for meta plugin %s",
483 i->c_str(),
484 plugin_name.c_str());
485 unload(i->c_str());
486 }
487 }
488}
489
490void
492{
493}
494
495void
497{
498 if (v->is_string()) {
499 pinfo_cache_.lock();
500 std::string p = std::string(v->path()).substr(meta_plugin_prefix_.length());
501 std::string s = std::string("Meta: ") + v->get_string();
502 std::list<std::pair<std::string, std::string>>::iterator i;
503 bool found = false;
504 for (i = pinfo_cache_.begin(); i != pinfo_cache_.end(); ++i) {
505 if (p == i->first) {
506 i->second = s;
507 found = true;
508 break;
509 }
510 }
511 if (!found) {
512 pinfo_cache_.push_back(make_pair(p, s));
513 }
514 pinfo_cache_.unlock();
515 }
516}
517
518void
520{
521}
522
523void
525{
526 pinfo_cache_.lock();
527 std::string p = std::string(path).substr(meta_plugin_prefix_.length());
528 std::list<std::pair<std::string, std::string>>::iterator i;
529 for (i = pinfo_cache_.begin(); i != pinfo_cache_.end(); ++i) {
530 if (p == i->first) {
531 pinfo_cache_.erase(i);
532 break;
533 }
534 }
535 pinfo_cache_.unlock();
536}
537
538void
539PluginManager::fam_event(const char *filename, unsigned int mask)
540{
541 const char *file_ext = "." SOEXT;
542
543 const char *pos = strstr(filename, file_ext);
544 std::string p = std::string(filename).substr(0, strlen(filename) - strlen(file_ext));
545 if (NULL != pos) {
546 pinfo_cache_.lock();
547 bool found = false;
548 std::list<std::pair<std::string, std::string>>::iterator i;
549 for (i = pinfo_cache_.begin(); i != pinfo_cache_.end(); ++i) {
550 if (p == i->first) {
551 found = true;
552 if ((mask & FAM_DELETE) || (mask & FAM_MOVED_FROM)) {
553 pinfo_cache_.erase(i);
554 } else {
555 try {
556 i->second = plugin_loader->get_description(p.c_str());
557 } catch (Exception &e) {
558 LibLogger::log_warn("PluginManager",
559 "Could not get possibly modified "
560 "description of plugin %s, exception follows",
561 p.c_str());
562 LibLogger::log_warn("PluginManager", e);
563 }
564 }
565 break;
566 }
567 }
568 if (!found && !(mask & FAM_ISDIR)
569 && ((mask & FAM_MODIFY) || (mask & FAM_MOVED_TO) || (mask & FAM_CREATE))) {
570#ifndef HAVE_LIBELF
571 if (plugin_loader->is_loaded(p.c_str())) {
572 LibLogger::log_info("PluginManager",
573 "Plugin %s changed on disk, but is "
574 "loaded, no new info can be loaded, keeping old.",
575 p.c_str());
576 }
577#endif
578 try {
579 std::string s = plugin_loader->get_description(p.c_str());
580 LibLogger::log_info("PluginManager", "Reloaded meta-data of %s on file change", p.c_str());
581 pinfo_cache_.push_back(make_pair(p, s));
582 } catch (Exception &e) {
583 // ignore, all it means is that the file has not been finished writing
584 /*
585 LibLogger::log_warn("PluginManager", "Could not get possibly modified "
586 "description of plugin %s, exception follows",
587 p.c_str());
588 LibLogger::log_warn("PluginManager", e);
589 */
590 }
591 }
592
593 pinfo_cache_.sort();
594 pinfo_cache_.unlock();
595 }
596}
597
598/** Add listener.
599 * Listeners are notified of plugin load and unloda events.
600 * @param listener listener to add
601 */
602void
604{
605 listeners_.lock();
606 listeners_.push_back(listener);
607 listeners_.sort();
608 listeners_.unique();
609 listeners_.unlock();
610}
611
612/** Remove listener.
613 * @param listener listener to remove
614 */
615void
617{
618 listeners_.remove_locked(listener);
619}
620
621void
622PluginManager::notify_loaded(const char *plugin_name)
623{
624 listeners_.lock();
625 for (lit_ = listeners_.begin(); lit_ != listeners_.end(); ++lit_) {
626 try {
627 (*lit_)->plugin_loaded(plugin_name);
628 } catch (Exception &e) {
629 LibLogger::log_warn("PluginManager",
630 "PluginManagerListener threw exception "
631 "during notification of plugin loaded, exception follows.");
632 LibLogger::log_warn("PluginManager", e);
633 }
634 }
635 listeners_.unlock();
636}
637
638void
639PluginManager::notify_unloaded(const char *plugin_name)
640{
641 listeners_.lock();
642 for (lit_ = listeners_.begin(); lit_ != listeners_.end(); ++lit_) {
643 try {
644 (*lit_)->plugin_unloaded(plugin_name);
645 } catch (Exception &e) {
646 LibLogger::log_warn("PluginManager",
647 "PluginManagerListener threw exception "
648 "during notification of plugin unloaded, exception follows.");
649 LibLogger::log_warn("PluginManager", e);
650 }
651 }
652 listeners_.unlock();
653}
654
655/** Lock plugin manager.
656 * This is an utility method that you can use for mutual access to the plugin
657 * manager. The mutex is not used internally, but meant to be used from
658 * callers.
659 */
660void
662{
663 mutex_->lock();
664}
665
666/** Try to lock plugin manager.
667 * This is an utility method that you can use for mutual access to the plugin
668 * manager. The mutex is not used internally, but meant to be used from
669 * callers.
670 * @return true if the lock was acquired, false otherwise
671 */
672bool
674{
675 return mutex_->try_lock();
676}
677
678/** Unlock plugin manager. */
679void
681{
682 mutex_->unlock();
683}
684
685} // end namespace fawkes
Plugin representation for JSON transfer.
Definition: Plugin.h:28
std::optional< std::string > name() const
Get name value.
Definition: Plugin.h:126
Thrown if a config entry could not be found.
Definition: config.h:47
Interface for configuration change handling.
Iterator interface to iterate over config values.
Definition: config.h:75
virtual const char * path() const =0
Path of value.
virtual bool next()=0
Check if there is another element and advance to this if possible.
virtual bool is_string() const =0
Check if current value is a string.
virtual std::string get_string() const =0
Get string value.
Interface for configuration handling.
Definition: config.h:68
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
Definition: config.cpp:619
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual bool is_list(const char *path)=0
Check if a value is a list.
virtual bool is_string(const char *path)=0
Check if a value is of type string.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
Definition: config.cpp:603
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
static const unsigned int FAM_MOVED_TO
File was moved to Y.
Definition: fam.h:48
static const unsigned int FAM_MODIFY
File was modified.
Definition: fam.h:41
static const unsigned int FAM_DELETE
Subfile was deleted.
Definition: fam.h:51
static const unsigned int FAM_ISDIR
Event occurred against dir.
Definition: fam.h:62
static const unsigned int FAM_MOVED_FROM
File was moved from X.
Definition: fam.h:47
static const unsigned int FAM_CREATE
Subfile was created.
Definition: fam.h:50
FileAlterationMonitor thread wrapper.
Definition: fam_thread.h:33
RefPtr< FileAlterationMonitor > get_fam()
Get FileAlterationMonitor.
Definition: fam_thread.cpp:55
static void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: liblogger.cpp:156
static void log_info(const char *component, const char *format,...)
Log informational message.
Definition: liblogger.cpp:138
static void log_error(const char *component, const char *format,...)
Log error message.
Definition: liblogger.cpp:174
static void log_debug(const char *component, const char *format,...)
Log debug message.
Definition: liblogger.cpp:120
virtual void unlock() const
Unlock list.
Definition: lock_list.h:138
virtual void lock() const
Lock list.
Definition: lock_list.h:124
Map with a lock.
Definition: lock_map.h:36
void lock() const
Lock list.
Definition: lock_map.h:91
RefPtr< Mutex > mutex() const
Get access to the internal mutex.
Definition: lock_map.h:133
void unlock() const
Unlock list.
Definition: lock_map.h:109
void erase_locked(const KeyType &key)
Remove item with lock.
Definition: lock_map.h:120
void set_open_flags(Module::ModuleFlags open_flags)
Set flags to open modules with.
ModuleFlags
Flags for the loading process.
Definition: module.h:44
Mutex locking helper.
Definition: mutex_locker.h:34
Mutex mutual exclusion lock.
Definition: mutex.h:33
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:117
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
This class manages plugins.
Definition: loader.h:58
bool is_loaded(const char *plugin_name)
Check if a plugin is loaded.
Definition: loader.cpp:348
ModuleManager * get_module_manager() const
Get module manager.
Definition: loader.cpp:141
std::string get_description(const char *plugin_name)
Get plugin description.
Definition: loader.cpp:323
Plugin * load(const char *plugin_name)
Load a specific plugin The plugin loader is clever and guarantees that every plugin is only loaded on...
Definition: loader.cpp:200
void unload(Plugin *plugin)
Unload the given plugin This will unload the given plugin.
Definition: loader.cpp:365
PluginManager listener.
Definition: listener.h:30
virtual void config_value_changed(const Configuration::ValueIterator *v)
Called whenever a watched value has changed.
Definition: manager.cpp:496
void remove_listener(PluginManagerListener *listener)
Remove listener.
Definition: manager.cpp:616
bool is_loaded(const std::string &plugin_name)
Check if plugin is loaded.
Definition: manager.cpp:257
~PluginManager()
Destructor.
Definition: manager.cpp:121
void unload(const std::string &plugin_name)
Unload plugin.
Definition: manager.cpp:427
virtual void config_comment_changed(const Configuration::ValueIterator *v)
Called whenever a comment of a watched value has changed.
Definition: manager.cpp:519
void init_pinfo_cache()
Initialize plugin info cache.
Definition: manager.cpp:161
std::list< std::pair< std::string, std::string > > get_available_plugins()
Generate list of all available plugins.
Definition: manager.cpp:218
virtual void fam_event(const char *filename, unsigned int mask)
Event has been raised.
Definition: manager.cpp:539
void add_listener(PluginManagerListener *listener)
Add listener.
Definition: manager.cpp:603
void load(const std::string &plugin_list)
Load plugin.
Definition: manager.cpp:325
std::list< std::string > get_loaded_plugins()
Get list of loaded plugins.
Definition: manager.cpp:234
void unlock()
Unlock plugin manager.
Definition: manager.cpp:680
virtual void config_tag_changed(const char *new_location)
Called whenever the tag has changed.
Definition: manager.cpp:491
PluginManager(ThreadCollector *thread_collector, Configuration *config, const char *meta_plugin_prefix, Module::ModuleFlags module_flags=Module::MODULE_FLAGS_DEFAULT, bool init_cache=true)
Constructor.
Definition: manager.cpp:85
bool try_lock()
Try to lock plugin manager.
Definition: manager.cpp:673
std::list< std::string > get_meta_plugin_children(const std::string &plugin_name)
Get meta plugin children.
Definition: manager.cpp:287
bool is_meta_plugin(const std::string &plugin_name)
Check if plugin is a meta plugin.
Definition: manager.cpp:272
virtual void config_value_erased(const char *path)
Called whenever a value has been erased from the config.
Definition: manager.cpp:524
void lock()
Lock plugin manager.
Definition: manager.cpp:661
void set_module_flags(Module::ModuleFlags flags)
Set flags to open modules with.
Definition: manager.cpp:154
Plugin interface class.
Definition: plugin.h:34
ThreadList & threads()
Get a list of threads.
Definition: plugin.cpp:111
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:50
virtual void force_remove(fawkes::ThreadList &tl)=0
Force removal of multiple threads.
virtual void add(ThreadList &tl)=0
Add multiple threads.
virtual void remove(ThreadList &tl)=0
Remove multiple threads.
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:499
void join()
Join the thread.
Definition: thread.cpp:597
void cancel()
Cancel a thread.
Definition: thread.cpp:646
Fawkes library namespace.
static std::string str_join(const std::vector< std::string > &v, char delim='/')
Join vector of strings string using given delimiter.
Definition: string_split.h:99