Update of /cvsroot/pclasses/pclasses2/src/System In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19443/src/System Modified Files: SharedLib.dl.cpp SharedLib.dyld.cpp SharedLib.generic.cpp SharedLib.ltdl.cpp SharedLib.shl.cpp SharedLib.win32.cpp Added Files: SharedLibCache.h Log Message: Added SharedLibCache to dl, shl, win32 impls. Added SharedLib::extension() --- NEW FILE: SharedLibCache.h --- /*************************************************************************** * Copyright (C) 2004 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef P_System_SharedLibCache_h #define P_System_SharedLibCache_h #include "pclasses/Phoenix.h" #include <map> #include <string> namespace P { namespace System { // Shared library handle cache template <typename destroyF> struct SharedLibCache { typedef std::map<std::string, unsigned long> map_t; enum { InvalidHandle = (unsigned long)-1 }; SharedLibCache() { } ~SharedLibCache() { destroyF fun; typename map_t::iterator it = _handles.begin(); while(_handles.end() != it) { fun(it->second); ++it; } _handles.clear(); } void add(const std::string& name, unsigned long handle) { map_t::iterator i = _handles.find(name); if(i == _handles.end()) _handles[name] = handle; } unsigned long lookup(const std::string& name) const { map_t::const_iterator i = _handles.find(name); if(i == _handles.end()) return InvalidHandle; return i->second; } CriticalSection mutex; private: map_t _handles; }; /** Internal marker type. */ struct cached_libs_context {}; template <typename destroyF> SharedLibCache<destroyF> & shared_lib_cache() { return ::P::Phoenix< SharedLibCache<destroyF>, cached_libs_context> ::instance(); } } // !namespace System } // !namespace P #endif Index: SharedLib.dl.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.dl.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- SharedLib.dl.cpp 24 Dec 2004 23:03:40 -0000 1.6 +++ SharedLib.dl.cpp 25 Dec 2004 07:02:16 -0000 1.7 @@ -19,6 +19,7 @@ ***************************************************************************/ #include "pclasses/System/SharedLib.h" +#include "SharedLibCache.h" #include <dlfcn.h> #include <errno.h> @@ -36,6 +37,16 @@ } int libdl_init_placeholder = (libdl_init(),0); +struct SharedLibCloser +{ + void operator()(unsigned long handle) + { + dlclose((void*)handle); + } +}; + +typedef SharedLibCache<SharedLibCloser> Cache; + int BindMode2Flags(SharedLib::BindMode mode) { int flags = 0; @@ -66,9 +77,24 @@ SharedLib::SharedLib(const std::string& name, BindMode mode) throw(SystemError) { - _handle = (unsigned long)dlopen(name.c_str(), BindMode2Flags(mode)); - if(!_handle) - throw SystemError(errno, dlerror(), P_SOURCEINFO); + Cache& cache = shared_lib_cache<SharedLibCloser>(); + CriticalSection::ScopedLock lck(cache.mutex); + + // se if we can get it from the handle cache ... + unsigned long handle = cache.lookup(name); + if(handle == Cache::InvalidHandle) + { + _handle = (unsigned long)dlopen(name.c_str(), BindMode2Flags(mode)); + if(!_handle) + throw SystemError(errno, dlerror(), P_SOURCEINFO); + + // add it to the handle cache + cache.add(name, _handle); + } + else + { + _handle = handle; + } } SharedLib::~SharedLib() throw() @@ -110,6 +136,12 @@ return addr; } +const char* SharedLib::extension() +{ + static const char* ext = "so"; + return ext; +} + } // !namespace System } // !namespace P Index: SharedLib.generic.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.generic.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- SharedLib.generic.cpp 25 Dec 2004 02:44:05 -0000 1.6 +++ SharedLib.generic.cpp 25 Dec 2004 07:02:16 -0000 1.7 @@ -83,5 +83,6 @@ return sh; } +} // !namespace System -} } // namespace P::System +} // !namespace P Index: SharedLib.dyld.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.dyld.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- SharedLib.dyld.cpp 25 Dec 2004 00:21:13 -0000 1.4 +++ SharedLib.dyld.cpp 25 Dec 2004 07:02:16 -0000 1.5 @@ -19,6 +19,7 @@ ***************************************************************************/ #include "pclasses/System/Sharedlib.h" +#include "SharedLibCache.h" #include <mach-o/dyld.h> @@ -94,6 +95,11 @@ return (void*)addr; } +const char* SharedLib::extension() +{ + static const char* ext = "dyld"; + return ext; +} } // !namespace System Index: SharedLib.ltdl.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.ltdl.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- SharedLib.ltdl.cpp 25 Dec 2004 00:11:49 -0000 1.4 +++ SharedLib.ltdl.cpp 25 Dec 2004 07:02:16 -0000 1.5 @@ -127,6 +127,13 @@ return addr; } +const char* SharedLib::extension() +{ + static const char* ext = "so"; + /*@fixme .. as far as i know libltdl is a sharedlib api abstraction lib, + where to get the default lib extension? */ + return ext; +} } // !namespace System Index: SharedLib.shl.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.shl.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- SharedLib.shl.cpp 25 Dec 2004 00:21:13 -0000 1.4 +++ SharedLib.shl.cpp 25 Dec 2004 07:02:16 -0000 1.5 @@ -19,6 +19,7 @@ ***************************************************************************/ #include "pclasses/System/SharedLib.h" +#include "SharedLibCache.h" #include <dl.h> #include <errno.h> @@ -30,6 +31,16 @@ namespace System { +struct SharedLibCloser +{ + void operator()(unsigned long handle) + { + shl_unload((shl_t*)handle); + } +}; + +typedef SharedLibCache<SharedLibCloser> Cache; + int BindMode2Flags(SharedLib::BindMode mode) { int flags = 0; @@ -64,18 +75,31 @@ // std::ostringstream realName; // realName << name; // realName << ".sl"; + Cache& cache = shared_lib_cache<SharedLibCloser>(); + CriticalSection::ScopedLock lck(cache.mutex); - _handle = (unsigned long)shl_load(name.str().c_str(), - BindMode2Flags(mode)); + // se if we have the handle cached ... + unsigned long handle = cache.lookup(name); + if(handle == Cache::InvalidHandle) + { + _handle = (unsigned long)shl_load(name.str().c_str(), + BindMode2Flags(mode)); - //@fixme dlerror() on hpux ?? - if(!_handle) - throw SystemError(errno, dlerror(), P_SOURCEINFO); + //@fixme dlerror() on hpux ?? + if(!_handle) + throw SystemError(errno, dlerror(), P_SOURCEINFO); + + // add the handle to the cache + cache.add(name, _handle); + } + else + { + _handle = handle; + } } SharedLib::~SharedLib() throw() { - shl_unload((shl_t*)_handle); } void* SharedLib::operator[](const char* symbol) throw(RuntimeError) @@ -87,6 +111,12 @@ return address; } +const char* SharedLib::extension() +{ + static const char* ext = "sl"; + return ext; +} + } // !namespace System } // !namespace P Index: SharedLib.win32.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/SharedLib.win32.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- SharedLib.win32.cpp 25 Dec 2004 00:21:13 -0000 1.4 +++ SharedLib.win32.cpp 25 Dec 2004 07:02:16 -0000 1.5 @@ -19,6 +19,8 @@ ***************************************************************************/ #include "pclasses/System/SharedLib.h" +#include "SharedLibCache.h" + #include <windows.h> #include <string> @@ -28,6 +30,16 @@ namespace System { +struct SharedLibCloser +{ + void operator()(unsigned long handle) + { + FreeLibrary((HMODULE)handle); + } +}; + +typedef SharedLibCache<SharedLibCloser> Cache; + SharedLib::SharedLib(const Unicode::String& name, BindMode mode) throw(SystemError) { // Unicode::String realName = name; @@ -44,15 +56,28 @@ // realName << name; // realName << ".dll"; - _handle = (unsigned long)LoadLibrary(name.c_str()); + Cache& cache = shared_lib_cache<SharedLibCloser>(); + CriticalSection::ScopedLock lck(cache.mutex); - if(!_handle) - throw SystemError(GetLastError(), "Could not load shared library", P_SOURCEINFO); + // se if we can get it from the handle cache ... + unsigned long handle = cache.lookup(name); + if(handle == Cache::InvalidHandle) + { + _handle = (unsigned long)LoadLibrary(name.c_str()); + if(!_handle) + throw SystemError(GetLastError(), "Could not load shared library", P_SOURCEINFO); + + // add the handle to the cache + cache.add(name, _handle); + } + else + { + _handle = handle; + } } SharedLib::~SharedLib() throw() { - FreeLibrary((HMODULE)_handle); } void* SharedLib::operator[](const char* symbol) throw(RuntimeError) @@ -64,6 +89,12 @@ return addr; } +const char* SharedLib::extension() +{ + static const char* ext = "dll"; + return ext; +} + } // !namespace System } // !namespace P |