Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00042 //----------------------------------------------------------------------------// 00043 00044 #include <dlfcn.h> 00045 #include <sys/types.h> 00046 #include <dirent.h> 00047 #include <stdlib.h> 00048 #include <string> 00049 #include <vector> 00050 #include <stdio.h> 00051 #include <errno.h> 00052 #include <string.h> 00053 00054 #include <boost/tokenizer.hpp> 00055 00056 #include "ClassFactory.h" 00057 #include "PluginLoader.h" 00058 00059 //----------------------------------------------------------------------------// 00060 00061 using namespace std; 00062 00063 //----------------------------------------------------------------------------// 00064 // Local namespace 00065 //----------------------------------------------------------------------------// 00066 00067 namespace { 00068 00069 void tokenize(const std::string &str, const std::string &delimiters, 00070 std::vector<std::string> &retItems) 00071 { 00072 typedef boost::tokenizer<boost::char_separator<char> > Tokenizer; 00073 boost::char_separator<char> sep(delimiters.c_str()); 00074 Tokenizer tok(str, sep); 00075 for (Tokenizer::iterator i = tok.begin(); i != tok.end(); ++i) { 00076 retItems.push_back(*i); 00077 } 00078 } 00079 00080 } 00081 00082 //----------------------------------------------------------------------------// 00083 00084 FIELD3D_NAMESPACE_OPEN 00085 00086 //----------------------------------------------------------------------------// 00087 // Static instances 00088 //----------------------------------------------------------------------------// 00089 00090 std::vector<std::string> PluginLoader::ms_pluginsLoaded; 00091 00092 //----------------------------------------------------------------------------// 00093 // PluginLoader implementations 00094 //----------------------------------------------------------------------------// 00095 00096 int filter(std::string &name) 00097 { 00098 std::string delimiters = "."; 00099 std::vector <std::string> items; 00100 00101 tokenize(name, delimiters, items); 00102 00103 if (items.size() == 0) { 00104 return 0; 00105 } 00106 00107 if (items[items.size() -1] == "so") { 00108 return 1; 00109 } 00110 00111 return 0; 00112 } 00113 00114 //----------------------------------------------------------------------------// 00115 00116 bool getDirSos(std::vector<std::string> &sos, std::string &dir) 00117 { 00118 struct dirent *dirent; 00119 00120 const char *ds = dir.c_str(); 00121 DIR *dirfd = opendir(ds); 00122 if (!dirfd) { 00123 std::string er = 00124 "Field3D_plugin loader: could not open directory " + dir + "\n"; 00125 //perror(er.c_str()); 00126 return false; 00127 } 00128 00129 dirent = readdir(dirfd); 00130 while (dirent != NULL) { 00131 00132 std::string name = dirent->d_name; 00133 00134 if (filter(name)) { 00135 name = dir + "/" + name; 00136 sos.push_back(name); 00137 } 00138 00139 dirent = readdir(dirfd); 00140 } 00141 00142 closedir(dirfd); 00143 00144 return true; 00145 } 00146 00147 //----------------------------------------------------------------------------// 00148 00149 PluginLoader::PluginLoader() 00150 { 00151 00152 } 00153 00154 //----------------------------------------------------------------------------// 00155 00156 PluginLoader::~PluginLoader() 00157 { 00158 00159 } 00160 00161 //----------------------------------------------------------------------------// 00162 00163 void PluginLoader::loadPlugins() 00164 { 00165 // Get environment variable 00166 char *cptr = getenv("FIELD3D_DSO_PATH"); 00167 if (!cptr) 00168 return; 00169 00170 std::string path = cptr; 00171 00172 // Split paths 00173 std::vector<std::string> paths; 00174 const std::string delimiters = ":"; 00175 00176 tokenize(path, delimiters, paths); 00177 00178 // For each path 00179 for (unsigned int i = 0; i < paths.size(); i++) { 00180 00181 // List the contents of the directory 00182 std::vector<std::string> sos; 00183 if (!getDirSos(sos,paths[i])) { 00184 continue; 00185 } 00186 00187 // Open each file 00188 for (unsigned int j = 0; j < sos.size(); j++) { 00189 std::string sofile = sos[j]; 00190 00191 //First check to see if a plugin of the same name has already been loaded 00192 const std::string pathDelimiter = "/"; 00193 std::vector<std::string> pluginName; 00194 tokenize(sofile, pathDelimiter, pluginName); 00195 00196 bool pluginAlreadyLoaded = false; 00197 00198 for (unsigned int i = 0; i < ms_pluginsLoaded.size(); i++) { 00199 if (pluginName.size() > 0) { 00200 if (ms_pluginsLoaded[i] == pluginName[pluginName.size() - 1]) { 00201 //This plugin has been loaded so look for another one 00202 //std::cout << ms_pluginsLoaded[i] << " is already loaded\n"; 00203 pluginAlreadyLoaded = true; 00204 break; 00205 } 00206 } 00207 } 00208 00209 if (pluginAlreadyLoaded) { 00210 continue; 00211 } 00212 00213 if (pluginName.size() > 0) { 00214 std::string lastName = pluginName[pluginName.size() -1]; 00215 ms_pluginsLoaded.push_back(lastName); 00216 } 00217 00218 00219 // Attempt to load .so file 00220 void *handle = dlopen(sofile.c_str(), RTLD_GLOBAL|RTLD_NOW); 00221 if (!handle) { 00222 std::cout << 00223 "Field3D Plugin loader: failed to load plugin: " << dlerror() << "\n"; 00224 continue; 00225 } 00226 00227 // Determine plugin type by looking for one of: 00228 // registerField3DPlugin() 00229 00230 int (*fptr)(ClassFactory &) = NULL; 00231 fptr = (int (*)(ClassFactory&)) 00232 dlsym(handle,"registerField3DPlugin"); 00233 std::string msg = "Initialized Field3D Plugin " + sofile; 00234 00235 char *dlsymError = dlerror(); 00236 if (!dlsymError) { 00237 if (fptr) { 00238 // Call the registration function 00239 int res = (*fptr)(ClassFactory::singleton()); 00240 if (!res) { 00241 Msg::print(Msg::SevWarning, 00242 "failed to init Field3D plugin " + sofile); 00243 } else { 00244 Msg::print(msg); 00245 } 00246 } 00247 } else { 00248 char *debugEnvVar = getenv("FIELD3D_DEBUG"); 00249 if (debugEnvVar) { 00250 // debug env var exist, so print warning 00251 Msg::print(Msg::SevWarning, 00252 "Field3D plugin loader: failed to load " 00253 "the symbol registerField3DPlugin"); 00254 } 00255 } 00256 } 00257 } 00258 } 00259 00260 //----------------------------------------------------------------------------// 00261 00262 #if 0 00263 00264 bool PluginLoader::getDso(char *cptr, const char *dso, 00265 std::string &dsoPath) 00266 { 00267 00268 std::string path = cptr; 00269 00270 // Split paths 00271 std::vector<std::string> paths; 00272 const std::string delimiters=":"; 00273 00274 Tokenize(path, paths, delimiters); 00275 00276 // For each path 00277 for (unsigned int i=0; i < paths.size(); i++) { 00278 struct dirent *dirent; 00279 00280 std::string dir = paths[i]; 00281 const char *ds = dir.c_str(); 00282 DIR *dirfd = opendir(ds); 00283 if (!dirfd) { 00284 continue; 00285 } 00286 00287 dirent = readdir(dirfd); 00288 while (dirent != NULL) { 00289 00290 std::string name = dirent->d_name; 00291 00292 if (name == dso) { 00293 dsoPath = dir + "/" + name; 00294 closedir(dirfd); 00295 return true; 00296 } 00297 00298 dirent = readdir(dirfd); 00299 } 00300 closedir(dirfd); 00301 } 00302 00303 00304 return false; 00305 00306 } 00307 00308 //----------------------------------------------------------------------------// 00309 00310 bool PluginLoader::resolveGlobalsForPlugins(const char *dso) { 00311 00312 // Get environment variable 00313 char *cptr = getenv("HOUDINI_DSO_PATH"); 00314 if (!cptr) 00315 return false; 00316 00317 std::string sofile; 00318 if (!getDso(cptr,dso,sofile)) { 00319 std::string dsostring = dso; 00320 Msg::print(dsostring + " is not in HOUDINI_DSO_PATH"); 00321 return false; 00322 } 00323 00324 void *handle = dlopen(sofile.c_str(), RTLD_GLOBAL|RTLD_NOW); 00325 00326 if (!handle) { 00327 std::cout << "Field3D Plugin loader: failed to load Houdini plugin: " 00328 << sofile << " " << dlerror() << "\n"; 00329 return false; 00330 } 00331 00332 #if 0 00333 Msg::print("---------------------------------------------------------"); 00334 Msg::print("Loaded " + sofile); 00335 Msg::print("---------------------------------------------------------"); 00336 #endif 00337 00338 return true; 00339 00340 } 00341 00342 #endif 00343 00344 //----------------------------------------------------------------------------// 00345 00346 FIELD3D_NAMESPACE_SOURCE_CLOSE 00347 00348 //----------------------------------------------------------------------------//