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