Fawkes API  Fawkes Development Version
module_manager.cpp
1 
2 /***************************************************************************
3  * module_manager.cpp - manager for modules (i.e. shared objects)
4  *
5  * Generated: Thu Jun 02 11:45:03 2011 (based on module_manager_template.h)
6  * Copyright 2006-2011 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 <core/threading/mutex.h>
25 #include <core/threading/mutex_locker.h>
26 #include <utils/system/dynamic_module/module_manager.h>
27 
28 namespace fawkes {
29 
30 /** @class ModuleManager <utils/system/dynamic_module/module_manager.h>
31  * Dynamic module manager.
32  * Manager to load and unload modules, keeps track of loaded modules
33  * and does not reload modules if they are already loaded.
34  * @author Tim Niemueller
35  */
36 
37 /** Constructor of NetworkManagerTemplate
38  * @param module_base_dir The module basedir where to look for plugins
39  * @param open_flags flags to pass to modules when opening them
40  */
41 ModuleManager::ModuleManager(const char *module_base_dir, Module::ModuleFlags open_flags)
42 {
43  modules_.clear();
44  module_base_dir_ = module_base_dir;
45  mutex_ = new Mutex();
46  open_flags_ = open_flags;
47 }
48 
49 /** Destructor. */
51 {
52  std::map<std::string, Module *>::iterator i;
53  for (i = modules_.begin(); i != modules_.end(); ++i) {
54  delete (*i).second;
55  }
56  modules_.clear();
57  delete mutex_;
58 }
59 
60 /** Set flags to open modules with.
61  * @param open_flags flags to pass to modules when opening them
62  */
63 void
65 {
66  open_flags_ = open_flags;
67 }
68 
69 /** Open a module
70  * @param filename The file name of the module that should be
71  * opened. If the ModuleManager implementation takes a base dir
72  * argument (recommended) this filename is relative to that
73  * base dir
74  * @return Returns the module if the file was opened successfully
75  * or NULL otherwise. Do NOT delete the module after usage but use
76  * closeModule to close it.
77  * @exception ModuleOpenException thrown if the module could not be opened
78  */
79 Module *
80 ModuleManager::open_module(const char *filename)
81 {
82  mutex_->lock();
83  if (modules_.find(filename) != modules_.end()) {
84  modules_[filename]->ref();
85  mutex_->unlock();
86  return modules_[filename];
87  } else {
88  Module *module = new Module(std::string(module_base_dir_) + "/" + filename, open_flags_);
89  try {
90  module->open();
91  // ref count of module is now 1
92  modules_[module->get_base_filename()] = module;
93  mutex_->unlock();
94  return module;
95  } catch (ModuleOpenException &e) {
96  delete module;
97  mutex_->unlock();
98  throw;
99  }
100  }
101  mutex_->unlock();
102 }
103 
104 /** Close a module by Module instance
105  * @param module The module that is to be closed
106  */
107 void
109 {
110  close_module(module->get_base_filename().c_str());
111 }
112 
113 /** Close a module by filename
114  * @param filename the name of the module file that should be closed, this
115  * is compared to loaded modules and must match what
116  * Module::GetBaseFilename() returns
117  */
118 void
119 ModuleManager::close_module(const char *filename)
120 {
121  mutex_->lock();
122  if (modules_.find(filename) != modules_.end()) {
123  modules_[filename]->unref();
124  if (modules_[filename]->notref()) {
125  delete modules_[filename];
126  modules_.erase(filename);
127  }
128  }
129  mutex_->unlock();
130 }
131 
132 /** Get a module if opened.
133  * This will return a pointer to a module if it had already been opened! The
134  * reference count is increased and you have to manually unref the module once
135  * you are done with it! This method works similar to open_module() with the
136  * difference that it is not tried to load the module if it is not open.
137  * @param filename file name of the module
138  * @return a pointer to the module with the reference cound incremented by one
139  * if the module had been opened already or NULL if it was not opened.
140  */
141 Module *
142 ModuleManager::get_module(const char *filename)
143 {
144  MutexLocker lock(mutex_);
145  if (modules_.find(filename) != modules_.end()) {
146  modules_[filename]->ref();
147  return modules_[filename];
148  } else {
149  return NULL;
150  }
151 }
152 
153 /** Check if the module is already opened.
154  * @param filename the name of the module file to check if it is opened.
155  * It is compared to loaded modules and must match what
156  * Module::get_base_filename() returns
157  * @return true if module has been opened, false otherwise
158  */
159 bool
160 ModuleManager::module_opened(const char *filename)
161 {
162  return (modules_.find(filename) != modules_.end());
163 }
164 
165 /** Get the file extension for the current module type.
166  * @return Returns a string with the file extension that has to
167  * be used for modules on the current system (for example "so")
168  */
169 const char *
171 {
173 }
174 
175 } // end of namespace fawkes
virtual ~ModuleManager()
Destructor.
virtual const char * get_module_file_extension()
Get the file extension for the current module type.
virtual void close_module(Module *module)
Close a module by Module instance.
virtual Module * get_module(const char *filename)
Get a module if opened.
virtual Module * open_module(const char *filename)
Open a module.
ModuleManager(const char *module_base_dir, Module::ModuleFlags open_flags=Module::MODULE_FLAGS_DEFAULT)
Constructor of NetworkManagerTemplate.
void set_open_flags(Module::ModuleFlags open_flags)
Set flags to open modules with.
virtual bool module_opened(const char *filename)
Check if the module is already opened.
Opening a module failed.
Definition: module.h:35
Dynamic module loader for Linux, FreeBSD, and MacOS X.
Definition: module.h:41
virtual std::string get_base_filename()
Get the base file name of the module.
Definition: module.cpp:279
ModuleFlags
Flags for the loading process.
Definition: module.h:44
virtual void open()
Open the module.
Definition: module.cpp:86
static const char * get_file_extension()
Get file extension for dl modules.
Definition: module.cpp:260
Mutex locking helper.
Definition: mutex_locker.h:34
Mutex mutual exclusion lock.
Definition: mutex.h:33
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
Fawkes library namespace.