backport SharedLibrary changes from 1.4.2-p1

This commit is contained in:
Marian Krivos 2011-11-04 18:56:08 +00:00
parent 5084562770
commit 97ec3f5bf6
16 changed files with 155 additions and 96 deletions

View File

@ -63,28 +63,60 @@ namespace Poco {
class Foundation_API SharedLibrary: private SharedLibraryImpl class Foundation_API SharedLibrary: private SharedLibraryImpl
/// The SharedLibrary class dynamically /// The SharedLibrary class dynamically
/// loads shared libraries at run-time. /// loads shared libraries at run-time.
{ {
public: public:
SharedLibrary(); enum Flags
/// Creates a SharedLibrary object. {
SHLIB_GLOBAL = 1,
/// On platforms that use dlopen(), use RTLD_GLOBAL. This is the default
/// if no flags are given.
///
/// This flag is ignored on platforms that do not use dlopen().
SHLIB_LOCAL = 2
/// On platforms that use dlopen(), use RTLD_LOCAL instead of RTLD_GLOBAL.
///
/// Note that if this flag is specified, RTTI (including dynamic_cast and throw) will
/// not work for types defined in the shared library with GCC and possibly other
/// compilers as well. See http://gcc.gnu.org/faq.html#dso for more information.
///
/// This flag is ignored on platforms that do not use dlopen().
};
SharedLibrary();
/// Creates a SharedLibrary object.
SharedLibrary(const std::string& path); SharedLibrary(const std::string& path);
/// Creates a SharedLibrary object and loads a library /// Creates a SharedLibrary object and loads a library
/// from the given path. /// from the given path.
virtual ~SharedLibrary(); SharedLibrary(const std::string& path, int flags);
/// Destroys the SharedLibrary. The actual library /// Creates a SharedLibrary object and loads a library
/// remains loaded. /// from the given path, using the given flags.
/// See the Flags enumeration for valid values.
virtual ~SharedLibrary();
/// Destroys the SharedLibrary. The actual library
/// remains loaded.
void load(const std::string& path); void load(const std::string& path);
/// Loads a shared library from the given path. /// Loads a shared library from the given path.
/// Throws a LibraryAlreadyLoadedException if /// Throws a LibraryAlreadyLoadedException if
/// a library has already been loaded. /// a library has already been loaded.
/// Throws a LibraryLoadException if the library /// Throws a LibraryLoadException if the library
/// cannot be loaded. /// cannot be loaded.
void unload(); void load(const std::string& path, int flags);
/// Loads a shared library from the given path,
/// using the given flags. See the Flags enumeration
/// for valid values.
/// Throws a LibraryAlreadyLoadedException if
/// a library has already been loaded.
/// Throws a LibraryLoadException if the library
/// cannot be loaded.
void unload();
/// Unloads a shared library. /// Unloads a shared library.
bool isLoaded() const; bool isLoaded() const;

View File

@ -51,12 +51,12 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); SharedLibraryImpl();
~SharedLibraryImpl(); ~SharedLibraryImpl();
void loadImpl(const std::string& path); void loadImpl(const std::string& path, int flags);
void unloadImpl(); void unloadImpl();
bool isLoadedImpl() const; bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name); void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -50,12 +50,18 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); enum Flags
~SharedLibraryImpl(); {
void loadImpl(const std::string& path); SHLIB_GLOBAL_IMPL = 1,
void unloadImpl(); SHLIB_LOCAL_IMPL = 2
bool isLoadedImpl() const; };
void* findSymbolImpl(const std::string& name);
SharedLibraryImpl();
~SharedLibraryImpl();
void loadImpl(const std::string& path, int flags);
void unloadImpl();
bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -50,12 +50,12 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); SharedLibraryImpl();
~SharedLibraryImpl(); ~SharedLibraryImpl();
void loadImpl(const std::string& path); void loadImpl(const std::string& path, int flags);
void unloadImpl(); void unloadImpl();
bool isLoadedImpl() const; bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name); void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -51,12 +51,12 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); SharedLibraryImpl();
~SharedLibraryImpl(); ~SharedLibraryImpl();
void loadImpl(const std::string& path); void loadImpl(const std::string& path, int flags);
void unloadImpl(); void unloadImpl();
bool isLoadedImpl() const; bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name); void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -50,12 +50,12 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); SharedLibraryImpl();
~SharedLibraryImpl(); ~SharedLibraryImpl();
void loadImpl(const std::string& path); void loadImpl(const std::string& path, int flags);
void unloadImpl(); void unloadImpl();
bool isLoadedImpl() const; bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name); void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -50,12 +50,12 @@ namespace Poco {
class Foundation_API SharedLibraryImpl class Foundation_API SharedLibraryImpl
{ {
protected: protected:
SharedLibraryImpl(); SharedLibraryImpl();
~SharedLibraryImpl(); ~SharedLibraryImpl();
void loadImpl(const std::string& path); void loadImpl(const std::string& path, int flags);
void unloadImpl(); void unloadImpl();
bool isLoadedImpl() const; bool isLoadedImpl() const;
void* findSymbolImpl(const std::string& name); void* findSymbolImpl(const std::string& name);
const std::string& getPathImpl() const; const std::string& getPathImpl() const;
static std::string suffixImpl(); static std::string suffixImpl();

View File

@ -63,7 +63,13 @@ SharedLibrary::SharedLibrary()
SharedLibrary::SharedLibrary(const std::string& path) SharedLibrary::SharedLibrary(const std::string& path)
{ {
loadImpl(path); loadImpl(path, 0);
}
SharedLibrary::SharedLibrary(const std::string& path, int flags)
{
loadImpl(path, flags);
} }
@ -74,7 +80,13 @@ SharedLibrary::~SharedLibrary()
void SharedLibrary::load(const std::string& path) void SharedLibrary::load(const std::string& path)
{ {
loadImpl(path); loadImpl(path, 0);
}
void SharedLibrary::load(const std::string& path, int flags)
{
loadImpl(path, flags);
} }

View File

@ -55,9 +55,9 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int /*flags*/)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_handle) throw LibraryAlreadyLoadedException(path); if (_handle) throw LibraryAlreadyLoadedException(path);
_handle = shl_load(path.c_str(), BIND_DEFERRED, 0); _handle = shl_load(path.c_str(), BIND_DEFERRED, 0);

View File

@ -62,16 +62,17 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int flags)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_handle) throw LibraryAlreadyLoadedException(path); if (_handle) throw LibraryAlreadyLoadedException(path);
int flags = RTLD_LAZY | RTLD_GLOBAL; int realFlags = RTLD_LAZY;
#if defined(RTLD_DEEPBIND) if (flags & SHLIB_LOCAL_IMPL)
flags |= RTLD_DEEPBIND; realFlags |= RTLD_LOCAL;
#endif else
_handle = dlopen(path.c_str(), flags); realFlags |= RTLD_GLOBAL;
_handle = dlopen(path.c_str(), realFlags);
if (!_handle) if (!_handle)
{ {
const char* err = dlerror(); const char* err = dlerror();

View File

@ -59,9 +59,9 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int /*flags*/)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (!_path.empty()) throw LibraryAlreadyLoadedException(path); if (!_path.empty()) throw LibraryAlreadyLoadedException(path);
_path = path; _path = path;

View File

@ -82,9 +82,9 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int /*flags*/)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_moduleId) throw LibraryAlreadyLoadedException(path); if (_moduleId) throw LibraryAlreadyLoadedException(path);
int fd = open(const_cast<char*>(path.c_str()), O_RDONLY, 0); int fd = open(const_cast<char*>(path.c_str()), O_RDONLY, 0);

View File

@ -56,17 +56,17 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int /*flags*/)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_handle) throw LibraryAlreadyLoadedException(_path); if (_handle) throw LibraryAlreadyLoadedException(_path);
DWORD flags(0); DWORD flags(0);
Path p(path); Path p(path);
if (p.isAbsolute()) flags |= LOAD_WITH_ALTERED_SEARCH_PATH; if (p.isAbsolute()) flags |= LOAD_WITH_ALTERED_SEARCH_PATH;
_handle = LoadLibraryExA(path.c_str(), 0, flags); _handle = LoadLibraryExA(path.c_str(), 0, flags);
if (!_handle) throw LibraryLoadException(path); if (!_handle) throw LibraryLoadException(path);
_path = path; _path = path;
} }

View File

@ -57,21 +57,21 @@ SharedLibraryImpl::~SharedLibraryImpl()
} }
void SharedLibraryImpl::loadImpl(const std::string& path) void SharedLibraryImpl::loadImpl(const std::string& path, int /*flags*/)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_handle) throw LibraryAlreadyLoadedException(_path); if (_handle) throw LibraryAlreadyLoadedException(_path);
DWORD flags(0); DWORD flags(0);
#if !defined(_WIN32_WCE) #if !defined(_WIN32_WCE)
Path p(path); Path p(path);
if (p.isAbsolute()) flags |= LOAD_WITH_ALTERED_SEARCH_PATH; if (p.isAbsolute()) flags |= LOAD_WITH_ALTERED_SEARCH_PATH;
#endif #endif
std::wstring upath; std::wstring upath;
UnicodeConverter::toUTF16(path, upath); UnicodeConverter::toUTF16(path, upath);
_handle = LoadLibraryExW(upath.c_str(), 0, flags); _handle = LoadLibraryExW(upath.c_str(), 0, flags);
if (!_handle) throw LibraryLoadException(path); if (!_handle) throw LibraryLoadException(path);
_path = path; _path = path;
} }
@ -98,17 +98,17 @@ void* SharedLibraryImpl::findSymbolImpl(const std::string& name)
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_handle) if (_handle)
{ {
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
std::wstring uname; std::wstring uname;
UnicodeConverter::toUTF16(name, uname); UnicodeConverter::toUTF16(name, uname);
return (void*) GetProcAddressW((HMODULE) _handle, uname.c_str()); return (void*) GetProcAddressW((HMODULE) _handle, uname.c_str());
#else #else
return (void*) GetProcAddress((HMODULE) _handle, name.c_str()); return (void*) GetProcAddress((HMODULE) _handle, name.c_str());
#endif #endif
} }
else return 0; else return 0;
} }

View File

@ -260,6 +260,8 @@ public:
/// ///
/// Does nothing if the key does not exist. /// Does nothing if the key does not exist.
void setPropertyEventingMode(bool enabled);
/// Enable/Disable property eventing.
protected: protected:
virtual bool getRaw(const std::string& key, std::string& value) const = 0; virtual bool getRaw(const std::string& key, std::string& value) const = 0;
/// If the property with the given key exists, stores the property's value /// If the property with the given key exists, stores the property's value
@ -301,6 +303,8 @@ private:
mutable int _depth; mutable int _depth;
mutable Poco::FastMutex _mutex; mutable Poco::FastMutex _mutex;
bool _propertyEventing;
friend class LayeredConfiguration; friend class LayeredConfiguration;
friend class ConfigurationView; friend class ConfigurationView;
friend class ConfigurationMapper; friend class ConfigurationMapper;

View File

@ -55,7 +55,7 @@ namespace Poco {
namespace Util { namespace Util {
AbstractConfiguration::AbstractConfiguration(): _depth(0) AbstractConfiguration::AbstractConfiguration(): _depth(0), _propertyEventing(true)
{ {
} }
@ -292,13 +292,13 @@ std::string AbstractConfiguration::expand(const std::string& value) const
void AbstractConfiguration::remove(const std::string& key) void AbstractConfiguration::remove(const std::string& key)
{ {
propertyRemoving(this, key); if (_propertyEventing) propertyRemoving(this, key);
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
removeRaw(key); removeRaw(key);
} }
propertyRemoved(this, key); if (_propertyEventing) propertyRemoved(this, key);
} }
@ -386,14 +386,18 @@ bool AbstractConfiguration::parseBool(const std::string& value)
void AbstractConfiguration::setRawWithEvent(const std::string& key, std::string value) void AbstractConfiguration::setRawWithEvent(const std::string& key, std::string value)
{ {
KeyValue kv(key, value); KeyValue kv(key, value);
propertyChanging(this, kv); if (_propertyEventing) propertyChanging(this, kv);
{ {
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
setRaw(key, value); setRaw(key, value);
} }
propertyChanged(this, kv); if (_propertyEventing) propertyChanged(this, kv);
} }
void AbstractConfiguration::setPropertyEventingMode(bool enabled)
{
_propertyEventing = enabled;
}
} } // namespace Poco::Util } } // namespace Poco::Util