fixed a fatal bug in DLL loading code: the deleted entries were never removed from the list of the loaded libraries
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15234 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -87,6 +87,10 @@ enum wxDLFlags
|
|||||||
wxDL_VERBATIM = 0x00000008, // Attempt to load the supplied library
|
wxDL_VERBATIM = 0x00000008, // Attempt to load the supplied library
|
||||||
// name without appending the usual dll
|
// name without appending the usual dll
|
||||||
// filename extension.
|
// filename extension.
|
||||||
|
|
||||||
|
wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
|
||||||
|
|
||||||
|
// FIXME: why? (VZ)
|
||||||
#ifdef __osf__
|
#ifdef __osf__
|
||||||
wxDL_DEFAULT = wxDL_LAZY
|
wxDL_DEFAULT = wxDL_LAZY
|
||||||
#else
|
#else
|
||||||
@@ -106,7 +110,7 @@ public:
|
|||||||
|
|
||||||
// return the platform standard DLL extension (with leading dot)
|
// return the platform standard DLL extension (with leading dot)
|
||||||
|
|
||||||
static const wxString &GetDllExt() { return ms_dllext; }
|
static const wxChar *GetDllExt() { return ms_dllext; }
|
||||||
|
|
||||||
wxDynamicLibrary() : m_handle(0) {}
|
wxDynamicLibrary() : m_handle(0) {}
|
||||||
wxDynamicLibrary(wxString libname, int flags = wxDL_DEFAULT)
|
wxDynamicLibrary(wxString libname, int flags = wxDL_DEFAULT)
|
||||||
@@ -155,7 +159,7 @@ protected:
|
|||||||
|
|
||||||
// Platform specific shared lib suffix.
|
// Platform specific shared lib suffix.
|
||||||
|
|
||||||
static const wxString ms_dllext;
|
static const wxChar *ms_dllext;
|
||||||
|
|
||||||
// the handle to DLL or NULL
|
// the handle to DLL or NULL
|
||||||
|
|
||||||
@@ -189,7 +193,7 @@ public:
|
|||||||
wxPluginLibrary( const wxString &libname, int flags = wxDL_DEFAULT );
|
wxPluginLibrary( const wxString &libname, int flags = wxDL_DEFAULT );
|
||||||
~wxPluginLibrary();
|
~wxPluginLibrary();
|
||||||
|
|
||||||
wxPluginLibrary *RefLib() { ++m_linkcount; return this; }
|
wxPluginLibrary *RefLib();
|
||||||
bool UnrefLib();
|
bool UnrefLib();
|
||||||
|
|
||||||
// These two are called by the PluginSentinel on (PLUGGABLE) object
|
// These two are called by the PluginSentinel on (PLUGGABLE) object
|
||||||
@@ -304,7 +308,7 @@ public:
|
|||||||
|
|
||||||
static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
|
static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
|
||||||
|
|
||||||
static const wxString &GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
|
static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -312,8 +316,6 @@ private:
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // wxUSE_DYNAMIC_LOADER
|
#endif // wxUSE_DYNAMIC_LOADER
|
||||||
#endif // _WX_DYNAMICLOADER_H__
|
#endif // _WX_DYNAMICLOADER_H__
|
||||||
|
|
||||||
// vi:sts=4:sw=4:et
|
|
||||||
|
@@ -65,12 +65,12 @@ const char *dlerror(void);
|
|||||||
// platform dependent files.
|
// platform dependent files.
|
||||||
|
|
||||||
#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
|
#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
|
||||||
const wxString wxDynamicLibrary::ms_dllext( _T(".dll") );
|
const wxChar *wxDynamicLibrary::ms_dllext( _T(".dll") );
|
||||||
#elif defined(__UNIX__)
|
#elif defined(__UNIX__)
|
||||||
#if defined(__HPUX__)
|
#if defined(__HPUX__)
|
||||||
const wxString wxDynamicLibrary::ms_dllext( _T(".sl") );
|
const wxChar *wxDynamicLibrary::ms_dllext( _T(".sl") );
|
||||||
#else
|
#else
|
||||||
const wxString wxDynamicLibrary::ms_dllext( _T(".so") );
|
const wxChar *wxDynamicLibrary::ms_dllext( _T(".so") );
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -287,9 +287,21 @@ class wxPluginLibraryModule : public wxModule
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxPluginLibraryModule() { }
|
wxPluginLibraryModule() { }
|
||||||
bool OnInit() { wxPluginLibrary::ms_classes = new wxDLImports(wxKEY_STRING); wxPluginManager::CreateManifest(); return TRUE; }
|
|
||||||
void OnExit() { delete wxPluginLibrary::ms_classes; wxPluginLibrary::ms_classes = NULL;
|
// TODO: create ms_classes on demand, why always preallocate it?
|
||||||
wxPluginManager::ClearManifest(); }
|
virtual bool OnInit()
|
||||||
|
{
|
||||||
|
wxPluginLibrary::ms_classes = new wxDLImports(wxKEY_STRING);
|
||||||
|
wxPluginManager::CreateManifest();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnExit()
|
||||||
|
{
|
||||||
|
delete wxPluginLibrary::ms_classes;
|
||||||
|
wxPluginLibrary::ms_classes = NULL;
|
||||||
|
wxPluginManager::ClearManifest();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(wxPluginLibraryModule )
|
DECLARE_DYNAMIC_CLASS(wxPluginLibraryModule )
|
||||||
@@ -312,7 +324,10 @@ wxPluginLibrary::wxPluginLibrary(const wxString &libname, int flags)
|
|||||||
RegisterModules();
|
RegisterModules();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
--m_linkcount; // Flag us for deletion
|
{
|
||||||
|
// Flag us for deletion
|
||||||
|
--m_linkcount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxPluginLibrary::~wxPluginLibrary()
|
wxPluginLibrary::~wxPluginLibrary()
|
||||||
@@ -324,14 +339,26 @@ wxPluginLibrary::~wxPluginLibrary()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxPluginLibrary *wxPluginLibrary::RefLib()
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( m_linkcount > 0, NULL,
|
||||||
|
_T("Library had been already deleted!") );
|
||||||
|
|
||||||
|
++m_linkcount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxPluginLibrary::UnrefLib()
|
bool wxPluginLibrary::UnrefLib()
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( m_objcount == 0, _T("Library unloaded before all objects were destroyed") );
|
wxASSERT_MSG( m_objcount == 0,
|
||||||
if( m_linkcount == 0 || --m_linkcount == 0 )
|
_T("Library unloaded before all objects were destroyed") );
|
||||||
|
|
||||||
|
if ( --m_linkcount == 0 )
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +497,7 @@ void wxPluginLibrary::UnregisterModules()
|
|||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// wxPluginLibrary
|
// wxPluginManager
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
wxDLManifest* wxPluginManager::ms_manifest = NULL;
|
wxDLManifest* wxPluginManager::ms_manifest = NULL;
|
||||||
@@ -479,17 +506,30 @@ wxDLManifest* wxPluginManager::ms_manifest = NULL;
|
|||||||
// Static accessors
|
// Static accessors
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
wxPluginLibrary *wxPluginManager::LoadLibrary(const wxString &libname, int flags)
|
wxPluginLibrary *
|
||||||
|
wxPluginManager::LoadLibrary(const wxString &libname, int flags)
|
||||||
{
|
{
|
||||||
wxString realname(libname);
|
wxString realname(libname);
|
||||||
|
|
||||||
if( !(flags & wxDL_VERBATIM) )
|
if( !(flags & wxDL_VERBATIM) )
|
||||||
realname += wxDynamicLibrary::GetDllExt();
|
realname += wxDynamicLibrary::GetDllExt();
|
||||||
|
|
||||||
wxPluginLibrary *entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
wxPluginLibrary *entry;
|
||||||
|
|
||||||
if( entry != 0 )
|
if ( flags & wxDL_NOSHARE )
|
||||||
{
|
{
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( entry )
|
||||||
|
{
|
||||||
|
wxLogTrace(_T("dll"),
|
||||||
|
_T("LoadLibrary(%s): already loaded."), realname.c_str());
|
||||||
|
|
||||||
entry->RefLib();
|
entry->RefLib();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -499,31 +539,64 @@ wxPluginLibrary *wxPluginManager::LoadLibrary(const wxString &libname, int flags
|
|||||||
if ( entry->IsLoaded() )
|
if ( entry->IsLoaded() )
|
||||||
{
|
{
|
||||||
ms_manifest->Put(realname, (wxObject*) entry);
|
ms_manifest->Put(realname, (wxObject*) entry);
|
||||||
|
|
||||||
|
wxLogTrace(_T("dll"),
|
||||||
|
_T("LoadLibrary(%s): loaded ok."), realname.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( entry->UnrefLib(), 0,
|
wxLogTrace(_T("dll"),
|
||||||
_T("Currently linked library is, ..not loaded??") );
|
_T("LoadLibrary(%s): failed to load."), realname.c_str());
|
||||||
entry = 0;
|
|
||||||
|
// we have created entry just above
|
||||||
|
if ( !entry->UnrefLib() )
|
||||||
|
{
|
||||||
|
// ... so UnrefLib() is supposed to delete it
|
||||||
|
wxFAIL_MSG( _T("Currently linked library is not loaded?") );
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxPluginManager::UnloadLibrary(const wxString& libname)
|
bool wxPluginManager::UnloadLibrary(const wxString& libname)
|
||||||
{
|
{
|
||||||
wxPluginLibrary *entry = (wxPluginLibrary*) ms_manifest->Get(libname);
|
wxString realname = libname;
|
||||||
|
|
||||||
|
wxPluginLibrary *entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
||||||
|
|
||||||
if ( !entry )
|
if ( !entry )
|
||||||
entry = (wxPluginLibrary*) ms_manifest->Get(libname + wxDynamicLibrary::GetDllExt());
|
{
|
||||||
|
realname += wxDynamicLibrary::GetDllExt();
|
||||||
|
|
||||||
if( entry )
|
entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
||||||
return entry->UnrefLib();
|
}
|
||||||
|
|
||||||
|
if ( !entry )
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("Attempt to unload library '%s' which is not loaded."),
|
||||||
|
libname.c_str());
|
||||||
|
|
||||||
wxLogDebug(_T("Attempt to Unlink library '%s' (which is not linked)."), libname.c_str());
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxLogTrace(_T("dll"), _T("UnloadLibrary(%s)"), realname.c_str());
|
||||||
|
|
||||||
|
if ( !entry->UnrefLib() )
|
||||||
|
{
|
||||||
|
// not really unloaded yet
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_manifest->Delete(realname);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY_2_2
|
#if WXWIN_COMPATIBILITY_2_2
|
||||||
wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
|
wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
|
||||||
{
|
{
|
||||||
@@ -534,9 +607,9 @@ wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
|
|||||||
if( ((wxPluginLibrary*)node->GetData())->GetLibHandle() == handle )
|
if( ((wxPluginLibrary*)node->GetData())->GetLibHandle() == handle )
|
||||||
return (wxPluginLibrary*)node->GetData();
|
return (wxPluginLibrary*)node->GetData();
|
||||||
|
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // WXWIN_COMPATIBILITY_2_2
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Class implementation
|
// Class implementation
|
||||||
@@ -574,19 +647,39 @@ void wxPluginManager::Unload()
|
|||||||
|
|
||||||
wxDllType wxDllLoader::LoadLibrary(const wxString &name)
|
wxDllType wxDllLoader::LoadLibrary(const wxString &name)
|
||||||
{
|
{
|
||||||
wxPluginLibrary *p = wxPluginManager::LoadLibrary(name, wxDL_DEFAULT | wxDL_VERBATIM);
|
wxPluginLibrary *p = wxPluginManager::LoadLibrary
|
||||||
return p->GetLibHandle();
|
(
|
||||||
|
name,
|
||||||
|
wxDL_DEFAULT | wxDL_VERBATIM | wxDL_NOSHARE
|
||||||
|
);
|
||||||
|
|
||||||
|
return p ? p->GetLibHandle() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDllLoader::UnloadLibrary(wxDllType handle)
|
void wxDllLoader::UnloadLibrary(wxDllType handle)
|
||||||
{
|
{
|
||||||
wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(handle);
|
wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(handle);
|
||||||
|
|
||||||
|
wxCHECK_RET( p, _T("Unloading a library not loaded with wxDllLoader?") );
|
||||||
|
|
||||||
p->UnrefLib();
|
p->UnrefLib();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
|
void *
|
||||||
|
wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
|
||||||
{
|
{
|
||||||
wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(dllHandle);
|
wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(dllHandle);
|
||||||
|
|
||||||
|
if ( !p )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( _T("Using a library not loaded with wxDllLoader?") );
|
||||||
|
|
||||||
|
if ( success )
|
||||||
|
*success = FALSE;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return p->GetSymbol(name, success);
|
return p->GetSymbol(name, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,4 +687,3 @@ void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *su
|
|||||||
|
|
||||||
#endif // wxUSE_DYNAMIC_LOADER
|
#endif // wxUSE_DYNAMIC_LOADER
|
||||||
|
|
||||||
// vi:sts=4:sw=4:et
|
|
||||||
|
Reference in New Issue
Block a user