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 
45 namespace fawkes {
46 
47 /// @cond INTERNALS
48 class plname_eq
49 {
50 public:
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 
61 private:
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  */
153 void
155 {
156  plugin_loader->get_module_manager()->set_open_flags(flags);
157 }
158 
159 /** Initialize plugin info cache. */
160 void
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  */
217 std::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  */
233 std::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  */
256 bool
257 PluginManager::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  */
271 bool
272 PluginManager::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  */
286 std::list<std::string>
287 PluginManager::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  */
300 std::list<std::string>
301 PluginManager::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  */
324 void
325 PluginManager::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  */
336 void
337 PluginManager::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());
402  } catch (CannotInitializeThreadException &e) {
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  */
426 void
427 PluginManager::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 
490 void
492 {
493 }
494 
495 void
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 
518 void
520 {
521 }
522 
523 void
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 
538 void
539 PluginManager::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  */
602 void
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  */
615 void
617 {
618  listeners_.remove_locked(listener);
619 }
620 
621 void
622 PluginManager::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 
638 void
639 PluginManager::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  */
660 void
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  */
672 bool
674 {
675  return mutex_->try_lock();
676 }
677 
678 /** Unlock plugin manager. */
679 void
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:72
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:65
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,...)
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