Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * module_manager.cpp - manager for modules (i.e. shared objects) 00004 * 00005 * Generated: Thu Jun 02 11:45:03 2011 (based on module_manager_template.h) 00006 * Copyright 2006-2011 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <utils/system/dynamic_module/module_manager.h> 00025 #include <core/threading/mutex.h> 00026 #include <core/threading/mutex_locker.h> 00027 00028 namespace fawkes { 00029 #if 0 /* just to make Emacs auto-indent happy */ 00030 } 00031 #endif 00032 00033 00034 /** @class ModuleManager <utils/system/dynamic_module/module_manager.h> 00035 * Dynamic module manager. 00036 * Manager to load and unload modules, keeps track of loaded modules 00037 * and does not reload modules if they are already loaded. 00038 * @author Tim Niemueller 00039 */ 00040 00041 /** Constructor of NetworkManagerTemplate 00042 * @param module_base_dir The module basedir where to look for plugins 00043 * @param open_flags flags to pass to modules when opening them 00044 */ 00045 ModuleManager::ModuleManager(const char *module_base_dir, 00046 Module::ModuleFlags open_flags) 00047 { 00048 __modules.clear(); 00049 __module_base_dir = module_base_dir; 00050 __mutex = new Mutex(); 00051 __open_flags = open_flags; 00052 } 00053 00054 /** Destructor. */ 00055 ModuleManager::~ModuleManager() 00056 { 00057 std::map<std::string, Module * >::iterator i; 00058 for (i = __modules.begin(); i != __modules.end(); ++i) { 00059 delete (*i).second; 00060 } 00061 __modules.clear(); 00062 delete __mutex; 00063 } 00064 00065 00066 /** Set flags to open modules with. 00067 * @param open_flags flags to pass to modules when opening them 00068 */ 00069 void 00070 ModuleManager::set_open_flags(Module::ModuleFlags open_flags) 00071 { 00072 __open_flags = open_flags; 00073 } 00074 00075 00076 /** Open a module 00077 * @param filename The file name of the module that should be 00078 * opened. If the ModuleManager implementation takes a base dir 00079 * argument (recommended) this filename is relative to that 00080 * base dir 00081 * @return Returns the module if the file was opened successfully 00082 * or NULL otherwise. Do NOT delete the module after usage but use 00083 * closeModule to close it. 00084 * @exception ModuleOpenException thrown if the module could not be opened 00085 */ 00086 Module * 00087 ModuleManager::open_module(const char *filename) 00088 { 00089 __mutex->lock(); 00090 if ( __modules.find(filename) != __modules.end() ) { 00091 __modules[filename]->ref(); 00092 __mutex->unlock(); 00093 return __modules[filename]; 00094 } else { 00095 Module *module = new Module(std::string(__module_base_dir) + "/" + filename, 00096 __open_flags); 00097 try { 00098 module->open(); 00099 // ref count of module is now 1 00100 __modules[module->get_base_filename()] = module; 00101 __mutex->unlock(); 00102 return module; 00103 } catch (ModuleOpenException &e) { 00104 delete module; 00105 __mutex->unlock(); 00106 throw; 00107 } 00108 } 00109 __mutex->unlock(); 00110 } 00111 00112 00113 /** Close a module by Module instance 00114 * @param module The module that is to be closed 00115 */ 00116 void 00117 ModuleManager::close_module(Module *module) 00118 { 00119 close_module(module->get_base_filename().c_str()); 00120 } 00121 00122 00123 /** Close a module by filename 00124 * @param filename the name of the module file that should be closed, this 00125 * is compared to loaded modules and must match what 00126 * Module::GetBaseFilename() returns 00127 */ 00128 void 00129 ModuleManager::close_module(const char *filename) 00130 { 00131 __mutex->lock(); 00132 if ( __modules.find(filename) != __modules.end() ) { 00133 __modules[filename]->unref(); 00134 if (__modules[filename]->notref()) { 00135 delete __modules[filename]; 00136 __modules.erase( filename ); 00137 } 00138 } 00139 __mutex->unlock(); 00140 } 00141 00142 00143 /** Get a module if opened. 00144 * This will return a pointer to a module if it had already been opened! The 00145 * reference count is increased and you have to manually unref the module once 00146 * you are done with it! This method works similar to open_module() with the 00147 * difference that it is not tried to load the module if it is not open. 00148 * @param filename file name of the module 00149 * @return a pointer to the module with the reference cound incremented by one 00150 * if the module had been opened already or NULL if it was not opened. 00151 */ 00152 Module * 00153 ModuleManager::get_module(const char *filename) 00154 { 00155 MutexLocker lock(__mutex); 00156 if ( __modules.find(filename) != __modules.end() ) { 00157 __modules[filename]->ref(); 00158 return __modules[filename]; 00159 } else { 00160 return NULL; 00161 } 00162 } 00163 00164 00165 /** Check if the module is already opened. 00166 * @param filename the name of the module file to check if it is opened. 00167 * It is compared to loaded modules and must match what 00168 * Module::get_base_filename() returns 00169 * @return true if module has been opened, false otherwise 00170 */ 00171 bool 00172 ModuleManager::module_opened(const char *filename) 00173 { 00174 return ( __modules.find(filename) != __modules.end() ); 00175 } 00176 00177 00178 /** Get the file extension for the current module type. 00179 * @return Returns a string with the file extension that has to 00180 * be used for modules on the current system (for example "so") 00181 */ 00182 const char * 00183 ModuleManager::get_module_file_extension() 00184 { 00185 return Module::get_file_extension(); 00186 } 00187 00188 } // end of namespace fawkes