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 <plugin/manager.h>
25 #include <plugin/listener.h>
26 #include <plugin/loader.h>
27 
28 #include <core/plugin.h>
29 #include <core/threading/thread_collector.h>
30 #include <core/threading/thread_initializer.h>
31 #include <core/threading/mutex_locker.h>
32 #include <core/exception.h>
33 #include <logging/liblogger.h>
34 #include <utils/system/fam_thread.h>
35 #include <config/config.h>
36 #include <utils/system/dynamic_module/module_manager.h>
37 
38 #include <algorithm>
39 #include <cstring>
40 #include <cstdlib>
41 #include <cerrno>
42 
43 #include <sys/types.h>
44 #include <dirent.h>
45 
46 namespace fawkes {
47 #if 0 /* just to make Emacs auto-indent happy */
48 }
49 #endif
50 
51 /// @cond INTERNALS
52 class plname_eq
53 {
54 public:
55  plname_eq(std::string name) {
56  __name = name;
57  }
58  bool operator()(Plugin *plugin)
59  {
60  return (__name == plugin->name());
61  }
62 private:
63  std::string __name;
64 };
65 /// @endcond INTERNALS
66 
67 /** @class PluginManager <plugin/manager.h>
68  * Fawkes Plugin Manager.
69  * This class provides a manager for the plugins used in fawkes. It can
70  * load and unload modules.
71  *
72  * @author Tim Niemueller
73  */
74 
75 /** Constructor.
76  * @param thread_collector thread manager plugin threads will be added to
77  * and removed from appropriately.
78  * @param config Fawkes configuration
79  * @param meta_plugin_prefix Path prefix for meta plugins
80  * @param module_flags flags to use to open plugin modules
81  * @param init_cache true to initialize the plugin cache, false to skip this
82  * step. Note that some functions like transmitting a list of available plugins
83  * is unavailable until the cache has been initialized. You can defer
84  * initialization of the cache if required.
85  */
87  Configuration *config,
88  const char *meta_plugin_prefix,
89  Module::ModuleFlags module_flags,
90  bool init_cache)
91  : ConfigurationChangeHandler(meta_plugin_prefix)
92 {
93  __mutex = new Mutex();
94  this->thread_collector = thread_collector;
95  plugin_loader = new PluginLoader(PLUGINDIR, config);
96  plugin_loader->get_module_manager()->set_open_flags(module_flags);
97  next_plugin_id = 1;
98  __config = config;
99  __meta_plugin_prefix = meta_plugin_prefix;
100 
101  if (init_cache) {
103  }
104 
105  __config->add_change_handler(this);
106 
107  __fam_thread = new FamThread();
108 #ifdef HAVE_INOTIFY
109  RefPtr<FileAlterationMonitor> fam = __fam_thread->get_fam();
110  fam->add_filter("^[^.].*\\." SOEXT "$");
111  fam->add_listener(this);
112  fam->watch_dir(PLUGINDIR);
113  __fam_thread->start();
114 #else
115  LibLogger::log_warn("PluginManager", "File alteration monitoring not available, "
116  "cannot detect changed plugins on disk.");
117 #endif
118 }
119 
120 
121 /** Destructor. */
123 {
124 #ifdef HAVE_INOTIFY
125  __fam_thread->cancel();
126  __fam_thread->join();
127 #endif
128  delete __fam_thread;
129  __config->rem_change_handler(this);
130  __pinfo_cache.lock();
131  __pinfo_cache.clear();
132  __pinfo_cache.unlock();
133  // Unload all plugins
134  for (rpit = plugins.rbegin(); rpit != plugins.rend(); ++rpit) {
135  try {
136  thread_collector->force_remove((*rpit)->threads());
137  } catch (Exception &e) {
138  // We want it to be quiet on destruction, i.e. Fawkes quitting
139  //LibLogger::log_warn("PluginManager", "Forced unloading of %s caused exception",
140  // (*rpit)->name());
141  //LibLogger::log_warn("PluginManager", e);
142  }
143  plugin_loader->unload(*rpit);
144  }
145  plugins.clear();
146  plugin_ids.clear();
147  delete plugin_loader;
148  delete __mutex;
149 }
150 
151 
152 /** Set flags to open modules with.
153  * @param flags flags to pass to modules when opening them
154  */
155 void
157 {
158  plugin_loader->get_module_manager()->set_open_flags(flags);
159 }
160 
161 
162 /** Initialize plugin info cache. */
163 void
165 {
166  __pinfo_cache.lock();
167 
168  DIR *plugin_dir;
169  struct dirent* dirp;
170  const char *file_ext = "." SOEXT;
171 
172  if ( NULL == (plugin_dir = opendir(PLUGINDIR)) ) {
173  throw Exception(errno, "Plugin directory %s could not be opened", PLUGINDIR);
174  }
175 
176  for (unsigned int i = 0; NULL != (dirp = readdir(plugin_dir)); ++i) {
177  char *file_name = dirp->d_name;
178  char *pos = strstr(file_name, file_ext);
179  std::string plugin_name = std::string(file_name).substr(0, strlen(file_name) - strlen(file_ext));
180  if (NULL != pos) {
181  try {
182  __pinfo_cache.push_back(make_pair(plugin_name,
183  plugin_loader->get_description(plugin_name.c_str())));
184  } catch (Exception &e) {
185  LibLogger::log_warn("PluginManager", "Could not get description of plugin %s, "
186  "exception follows", 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 
253 /** Check if plugin is loaded.
254  * @param plugin_name plugin to check if it is loaded
255  * @return true if the plugin is currently loaded, false otherwise
256  */
257 bool
258 PluginManager::is_loaded(const char *plugin_name)
259 {
260  if (plugin_loader->is_loaded(plugin_name)) {
261  return true;
262  } else {
263  // Could still be a meta plugin
264  return (__meta_plugins.find(plugin_name) != __meta_plugins.end());
265  }
266 }
267 
268 
269 /** Parse a list of plugin types.
270  * Takes a comma-separated list of plugins and parses them into the individual
271  * plugin names.
272  * @param plugin_type_list string containing a comma-separated list of plugin types
273  * @return parsed list of plugin types
274  */
275 std::list<std::string>
276 PluginManager::parse_plugin_list(const char *plugin_list)
277 {
278  std::list<std::string> rv;
279 
280  char *plugins = strdup(plugin_list);
281  char *saveptr;
282  char *plugin;
283 
284  plugin = strtok_r(plugins, ",", &saveptr);
285  while ( plugin ) {
286  rv.push_back(plugin);
287  plugin = strtok_r(NULL, ",", &saveptr);
288  }
289  free(plugins);
290 
291  return rv;
292 }
293 
294 
295 /** Load plugin.
296  * The loading is interrupted if any of the plugins does not load properly.
297  * The already loaded plugins are *not* unloaded, but kept.
298  * @param plugin_list string containing a comma-separated list of plugins
299  * to load. The plugin list can contain meta plugins.
300  */
301 void
302 PluginManager::load(const char *plugin_list)
303 {
304  std::list<std::string> pp = parse_plugin_list(plugin_list);
305 
306  for (std::list<std::string>::iterator i = pp.begin(); i != pp.end(); ++i) {
307  if ( i->length() == 0 ) continue;
308 
309  bool try_real_plugin = true;
310  if ( __meta_plugins.find(*i) == __meta_plugins.end() ) {
311  std::string meta_plugin = __meta_plugin_prefix + *i;
312  bool found_meta = false;
313  std::string pset = "";
314  try {
315  pset = __config->get_string(meta_plugin.c_str());
316  found_meta = true;
317  } catch (ConfigEntryNotFoundException &e) {
318  // no meta plugin defined by that name
319  //printf("No meta plugin defined with the name %s\n", i->c_str());
320  try_real_plugin = true;
321  }
322 
323  if (found_meta) {
324  if (pset.length() == 0) {
325  throw Exception("Refusing to load an empty meta plugin");
326  }
327  //printf("Going to load meta plugin %s (%s)\n", i->c_str(), pset.c_str());
328  __meta_plugins.lock();
329  // Setting has to happen here, so that a meta plugin will not cause an
330  // endless loop if it references itself!
331  __meta_plugins[*i] = pset;
332  __meta_plugins.unlock();
333  try {
334  LibLogger::log_info("PluginManager", "Loading plugins %s for meta plugin %s",
335  pset.c_str(), i->c_str());
336  load(pset.c_str());
337  notify_loaded(i->c_str());
338  } catch (Exception &e) {
339  e.append("Could not initialize meta plugin %s, aborting loading.", i->c_str());
340  __meta_plugins.erase_locked(*i);
341  throw;
342  }
343 
344  try_real_plugin = false;
345  }
346  }
347 
348  if (try_real_plugin &&
349  (find_if(plugins.begin(), plugins.end(), plname_eq(*i)) == plugins.end()))
350  {
351  try {
352  //printf("Going to load real plugin %s\n", i->c_str());
353  Plugin *plugin = plugin_loader->load(i->c_str());
354  plugins.lock();
355  try {
356  thread_collector->add(plugin->threads());
357  plugins.push_back(plugin);
358  plugin_ids[*i] = next_plugin_id++;
359  notify_loaded(i->c_str());
360  } catch (CannotInitializeThreadException &e) {
361  e.prepend("Plugin >>> %s <<< could not be initialized, unloading", i->c_str());
362  plugins.unlock();
363  plugin_loader->unload(plugin);
364  throw;
365  }
366  plugins.unlock();
367  } catch (Exception &e) {
368  MutexLocker lock(__meta_plugins.mutex());
369  if ( __meta_plugins.find(*i) == __meta_plugins.end() ) {
370  // only throw exception if no meta plugin with that name has
371  // already been loaded
372  throw;
373  }
374  }
375  }
376  }
377 }
378 
379 
380 /** Unload plugin.
381  * Note that this method does not allow to pass a list of plugins, but it will
382  * only accept a single plugin at a time.
383  * @param plugin_name plugin to unload, can be a meta plugin.
384  */
385 void
386 PluginManager::unload(const char *plugin_name)
387 {
388  MutexLocker lock(plugins.mutex());
389  if ( (pit = find_if(plugins.begin(), plugins.end(), plname_eq(plugin_name)))
390  != plugins.end()) {
391  try {
392  thread_collector->remove((*pit)->threads());
393  plugin_loader->unload(*pit);
394  plugins.erase(pit);
395  plugin_ids.erase(plugin_name);
396  notify_unloaded(plugin_name);
397  // find all meta plugins that required this module, this can no longer
398  // be considered loaded
399  __meta_plugins.lock();
400  __mpit = __meta_plugins.begin();
401  while (__mpit != __meta_plugins.end()) {
402  std::list<std::string> pp = parse_plugin_list(__mpit->second.c_str());
403 
404  bool erase = false;
405  for (std::list<std::string>::iterator i = pp.begin(); i != pp.end(); ++i) {
406  if ( *i == plugin_name ) {
407  erase = true;
408  break;
409  }
410  }
411  if ( erase ) {
413  ++__mpit;
414  notify_unloaded(tmp->first.c_str());
415  __meta_plugins.erase(tmp);
416  } else {
417  ++__mpit;
418  }
419  }
420  __meta_plugins.unlock();
421 
422  } catch (Exception &e) {
423  LibLogger::log_error("PluginManager", "Could not finalize one or more threads of plugin %s, NOT unloading plugin", plugin_name);
424  throw;
425  }
426  } else if (__meta_plugins.find(plugin_name) != __meta_plugins.end()) {
427  std::list<std::string> pp = parse_plugin_list(__meta_plugins[plugin_name].c_str());
428 
429  for (std::list<std::string>::reverse_iterator i = pp.rbegin(); i != pp.rend(); ++i) {
430  if ( i->length() == 0 ) continue;
431  if ((find_if(plugins.begin(), plugins.end(), plname_eq(*i)) == plugins.end())
432  && (__meta_plugins.find(*i) != __meta_plugins.end()) ) {
433  continue;
434  }
435 
436  __meta_plugins.erase_locked(*i);
437  LibLogger::log_info("PluginManager", "UNloading plugin %s for meta plugin %s",
438  i->c_str(), plugin_name);
439  unload(i->c_str());
440  }
441  }
442 }
443 
444 
445 void
447 {
448 }
449 
450 void
452 {
453  if (v->is_string()) {
454  __pinfo_cache.lock();
455  std::string p = std::string(v->path()).substr(__meta_plugin_prefix.length());
456  std::string s = std::string("Meta: ") + v->get_string();
457  std::list<std::pair<std::string, std::string> >::iterator i;
458  bool found = false;
459  for (i = __pinfo_cache.begin(); i != __pinfo_cache.end(); ++i) {
460  if (p == i->first) {
461  i->second = s;
462  found = true;
463  break;
464  }
465  }
466  if (! found) {
467  __pinfo_cache.push_back(make_pair(p, s));
468  }
469  __pinfo_cache.unlock();
470  }
471 }
472 
473 void
475 {
476 }
477 
478 void
480 {
481  __pinfo_cache.lock();
482  std::string p = std::string(path).substr(__meta_plugin_prefix.length());
483  std::list<std::pair<std::string, std::string> >::iterator i;
484  for (i = __pinfo_cache.begin(); i != __pinfo_cache.end(); ++i) {
485  if (p == i->first) {
486  __pinfo_cache.erase(i);
487  break;
488  }
489  }
490  __pinfo_cache.unlock();
491 }
492 
493 
494 void
495 PluginManager::fam_event(const char *filename, unsigned int mask)
496 {
497  const char *file_ext = "." SOEXT;
498 
499  const char *pos = strstr(filename, file_ext);
500  std::string p = std::string(filename).substr(0, strlen(filename) - strlen(file_ext));
501  if (NULL != pos) {
502  __pinfo_cache.lock();
503  bool found = false;
504  std::list<std::pair<std::string, std::string> >::iterator i;
505  for (i = __pinfo_cache.begin(); i != __pinfo_cache.end(); ++i) {
506  if (p == i->first) {
507  found = true;
508  if ((mask & FAM_DELETE) || (mask & FAM_MOVED_FROM)) {
509  __pinfo_cache.erase(i);
510  } else {
511  try {
512  i->second = plugin_loader->get_description(p.c_str());
513  } catch (Exception &e) {
514  LibLogger::log_warn("PluginManager", "Could not get possibly modified "
515  "description of plugin %s, exception follows",
516  p.c_str());
517  LibLogger::log_warn("PluginManager", e);
518  }
519  }
520  break;
521  }
522  }
523  if (! found &&
524  !(mask & FAM_ISDIR) &&
525  ((mask & FAM_MODIFY) || (mask & FAM_MOVED_TO) || (mask & FAM_CREATE))) {
526 #ifndef HAVE_LIBELF
527  if (plugin_loader->is_loaded(p.c_str())) {
528  LibLogger::log_info("PluginManager", "Plugin %s changed on disk, but is "
529  "loaded, no new info can be loaded, keeping old.",
530  p.c_str());
531  }
532 #endif
533  try {
534  std::string s = plugin_loader->get_description(p.c_str());
535  LibLogger::log_info("PluginManager", "Reloaded meta-data of %s on file change",
536  p.c_str());
537  __pinfo_cache.push_back(make_pair(p, s));
538  } catch (Exception &e) {
539  // ignore, all it means is that the file has not been finished writing
540  /*
541  LibLogger::log_warn("PluginManager", "Could not get possibly modified "
542  "description of plugin %s, exception follows",
543  p.c_str());
544  LibLogger::log_warn("PluginManager", e);
545  */
546  }
547  }
548 
549  __pinfo_cache.sort();
550  __pinfo_cache.unlock();
551  }
552 }
553 
554 
555 /** Add listener.
556  * Listeners are notified of plugin load and unloda events.
557  * @param listener listener to add
558  */
559 void
561 {
562  __listeners.lock();
563  __listeners.push_back(listener);
564  __listeners.sort();
565  __listeners.unique();
566  __listeners.unlock();
567 }
568 
569 /** Remove listener.
570  * @param listener listener to remove
571  */
572 void
574 {
575  __listeners.remove_locked(listener);
576 }
577 
578 void
579 PluginManager::notify_loaded(const char *plugin_name)
580 {
581  __listeners.lock();
582  for (__lit = __listeners.begin(); __lit != __listeners.end(); ++__lit) {
583  try {
584  (*__lit)->plugin_loaded(plugin_name);
585  } catch (Exception &e) {
586  LibLogger::log_warn("PluginManager", "PluginManagerListener threw exception "
587  "during notification of plugin loaded, exception follows.");
588  LibLogger::log_warn("PluginManager", e);
589  }
590  }
591  __listeners.unlock();
592 }
593 
594 void
595 PluginManager::notify_unloaded(const char *plugin_name)
596 {
597  __listeners.lock();
598  for (__lit = __listeners.begin(); __lit != __listeners.end(); ++__lit) {
599  try {
600  (*__lit)->plugin_unloaded(plugin_name);
601  } catch (Exception &e) {
602  LibLogger::log_warn("PluginManager", "PluginManagerListener threw exception "
603  "during notification of plugin unloaded, exception follows.");
604  LibLogger::log_warn("PluginManager", e);
605  }
606  }
607  __listeners.unlock();
608 }
609 
610 
611 /** Lock plugin manager.
612  * This is an utility method that you can use for mutual access to the plugin
613  * manager. The mutex is not used internally, but meant to be used from
614  * callers.
615  */
616 void
618 {
619  __mutex->lock();
620 }
621 
622 
623 /** Try to lock plugin manager.
624  * This is an utility method that you can use for mutual access to the plugin
625  * manager. The mutex is not used internally, but meant to be used from
626  * callers.
627  * @return true if the lock was acquired, false otherwise
628  */
629 bool
631 {
632  return __mutex->try_lock();
633 }
634 
635 /** Unlock plugin manager. */
636 void
638 {
639  __mutex->unlock();
640 }
641 
642 } // end namespace fawkes
void set_open_flags(Module::ModuleFlags open_flags)
Set flags to open modules with.
static void log_info(const char *component, const char *format,...)
Log informational message.
Definition: liblogger.cpp:144
~PluginManager()
Destructor.
Definition: manager.cpp:122
Plugin interface class.
Definition: plugin.h:33
void set_module_flags(Module::ModuleFlags flags)
Set flags to open modules with.
Definition: manager.cpp:156
void erase_locked(const KeyType &key)
Remove item with lock.
Definition: lock_map.h:132
void lock() const
Lock list.
Definition: lock_map.h:100
virtual void lock() const
Lock list.
Definition: lock_list.h:128
virtual void fam_event(const char *filename, unsigned int mask)
Event has been raised.
Definition: manager.cpp:495
virtual void remove(ThreadList &tl)=0
Remove multiple threads.
std::list< std::pair< std::string, std::string > > get_available_plugins()
Generate list of all available plugins.
Definition: manager.cpp:218
void init_pinfo_cache()
Initialize plugin info cache.
Definition: manager.cpp:164
Fawkes library namespace.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
bool try_lock()
Try to lock plugin manager.
Definition: manager.cpp:630
Mutex locking helper.
Definition: mutex_locker.h:33
Interface for configuration change handling.
virtual void config_comment_changed(const Configuration::ValueIterator *v)
Called whenever a comment of a watched value has changed.
Definition: manager.cpp:474
Thrown if a config entry could not be found.
Definition: config.h:48
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
static const unsigned int FAM_CREATE
Subfile was created.
Definition: fam.h:50
Thread collector.
virtual bool next()=0
Check if there is another element and advance to this if possible.
RefPtr< FileAlterationMonitor > get_fam()
Get FileAlterationMonitor.
Definition: fam_thread.cpp:58
ThreadList & threads()
Get a list of threads.
Definition: plugin.cpp:110
static const unsigned int FAM_ISDIR
Event occurred against dir.
Definition: fam.h:62
This class manages plugins.
Definition: loader.h:61
ModuleFlags
Flags for the loading process.
Definition: module.h:44
Map with a lock.
Definition: lock_map.h:37
void lock()
Lock plugin manager.
Definition: manager.cpp:617
PluginManager listener.
Definition: listener.h:32
void add_listener(PluginManagerListener *listener)
Add listener.
Definition: manager.cpp:560
static void log_error(const char *component, const char *format,...)
Log error message.
Definition: liblogger.cpp:180
void unload(Plugin *plugin)
Unload the given plugin This will unload the given plugin.
Definition: loader.cpp:376
Thread cannot be initialized.
virtual bool is_string() const =0
Check if current value is a string.
virtual void config_tag_changed(const char *new_location)
Called whenever the tag has changed.
Definition: manager.cpp:446
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual void force_remove(fawkes::ThreadList &tl)=0
Force removal of multiple threads.
void load(const char *plugin_list)
Load plugin.
Definition: manager.cpp:302
virtual void rem_change_handler(ConfigurationChangeHandler *h)
Remove a configuration change handler.
Definition: config.cpp:564
void prepend(const char *format,...)
Prepend messages to the message list.
Definition: exception.cpp:322
void remove_listener(PluginManagerListener *listener)
Remove listener.
Definition: manager.cpp:573
virtual void unlock() const
Unlock list.
Definition: lock_list.h:144
void unlock() const
Unlock list.
Definition: lock_map.h:120
std::list< std::string > get_loaded_plugins()
Get list of loaded plugins.
Definition: manager.cpp:234
std::string get_description(const char *plugin_name)
Get plugin description.
Definition: loader.cpp:333
void unload(const char *plugin_name)
Unload plugin.
Definition: manager.cpp:386
virtual std::string get_string() const =0
Get string value.
static const unsigned int FAM_MOVED_FROM
File was moved from X.
Definition: fam.h:47
virtual const char * path() const =0
Path of value.
virtual void add(ThreadList &tl)=0
Add multiple threads.
static const unsigned int FAM_MOVED_TO
File was moved to Y.
Definition: fam.h:48
static void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: liblogger.cpp:162
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:86
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:120
void cancel()
Cancel a thread.
Definition: thread.cpp:651
virtual void config_value_changed(const Configuration::ValueIterator *v)
Called whenever a watched value has changed.
Definition: manager.cpp:451
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:49
virtual void config_value_erased(const char *path)
Called whenever a value has been erased from the config.
Definition: manager.cpp:479
bool is_loaded(const char *plugin_name)
Check if plugin is loaded.
Definition: manager.cpp:258
Iterator interface to iterate over config values.
Definition: config.h:72
void join()
Join the thread.
Definition: thread.cpp:610
FileAlterationMonitor thread wrapper.
Definition: fam_thread.h:35
void lock()
Lock this mutex.
Definition: mutex.cpp:89
virtual void add_change_handler(ConfigurationChangeHandler *h)
Add a configuration change handler.
Definition: config.cpp:547
static const unsigned int FAM_DELETE
Subfile was deleted.
Definition: fam.h:51
static const unsigned int FAM_MODIFY
File was modified.
Definition: fam.h:41
void unlock()
Unlock plugin manager.
Definition: manager.cpp:637
ModuleManager * get_module_manager() const
Get module manager.
Definition: loader.cpp:151
bool is_loaded(const char *plugin_name)
Check if a plugin is loaded.
Definition: loader.cpp:358
Mutex mutual exclusion lock.
Definition: mutex.h:32
Interface for configuration handling.
Definition: config.h:67
RefPtr< Mutex > mutex() const
Get access to the internal mutex.
Definition: lock_map.h:146
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:511
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:211