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
|
||||
// name without appending the usual dll
|
||||
// filename extension.
|
||||
|
||||
wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
|
||||
|
||||
// FIXME: why? (VZ)
|
||||
#ifdef __osf__
|
||||
wxDL_DEFAULT = wxDL_LAZY
|
||||
#else
|
||||
@@ -106,7 +110,7 @@ public:
|
||||
|
||||
// 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(wxString libname, int flags = wxDL_DEFAULT)
|
||||
@@ -155,7 +159,7 @@ protected:
|
||||
|
||||
// Platform specific shared lib suffix.
|
||||
|
||||
static const wxString ms_dllext;
|
||||
static const wxChar *ms_dllext;
|
||||
|
||||
// the handle to DLL or NULL
|
||||
|
||||
@@ -189,7 +193,7 @@ public:
|
||||
wxPluginLibrary( const wxString &libname, int flags = wxDL_DEFAULT );
|
||||
~wxPluginLibrary();
|
||||
|
||||
wxPluginLibrary *RefLib() { ++m_linkcount; return this; }
|
||||
wxPluginLibrary *RefLib();
|
||||
bool UnrefLib();
|
||||
|
||||
// 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 const wxString &GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
|
||||
static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -312,8 +316,6 @@ private:
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif // wxUSE_DYNAMIC_LOADER
|
||||
#endif // _WX_DYNAMICLOADER_H__
|
||||
|
||||
// vi:sts=4:sw=4:et
|
||||
|
@@ -65,13 +65,13 @@ const char *dlerror(void);
|
||||
// platform dependent files.
|
||||
|
||||
#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
|
||||
const wxString wxDynamicLibrary::ms_dllext( _T(".dll") );
|
||||
const wxChar *wxDynamicLibrary::ms_dllext( _T(".dll") );
|
||||
#elif defined(__UNIX__)
|
||||
#if defined(__HPUX__)
|
||||
const wxString wxDynamicLibrary::ms_dllext( _T(".sl") );
|
||||
#else
|
||||
const wxString wxDynamicLibrary::ms_dllext( _T(".so") );
|
||||
#endif
|
||||
#if defined(__HPUX__)
|
||||
const wxChar *wxDynamicLibrary::ms_dllext( _T(".sl") );
|
||||
#else
|
||||
const wxChar *wxDynamicLibrary::ms_dllext( _T(".so") );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
wxDllType wxDynamicLibrary::GetProgramHandle()
|
||||
@@ -286,10 +286,22 @@ wxDLImports* wxPluginLibrary::ms_classes = NULL;
|
||||
class wxPluginLibraryModule : public wxModule
|
||||
{
|
||||
public:
|
||||
wxPluginLibraryModule() {}
|
||||
bool OnInit() { wxPluginLibrary::ms_classes = new wxDLImports(wxKEY_STRING); wxPluginManager::CreateManifest(); return TRUE; }
|
||||
void OnExit() { delete wxPluginLibrary::ms_classes; wxPluginLibrary::ms_classes = NULL;
|
||||
wxPluginManager::ClearManifest(); }
|
||||
wxPluginLibraryModule() { }
|
||||
|
||||
// TODO: create ms_classes on demand, why always preallocate it?
|
||||
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:
|
||||
DECLARE_DYNAMIC_CLASS(wxPluginLibraryModule )
|
||||
@@ -312,7 +324,10 @@ wxPluginLibrary::wxPluginLibrary(const wxString &libname, int flags)
|
||||
RegisterModules();
|
||||
}
|
||||
else
|
||||
--m_linkcount; // Flag us for deletion
|
||||
{
|
||||
// Flag us for deletion
|
||||
--m_linkcount;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
wxASSERT_MSG( m_objcount == 0, _T("Library unloaded before all objects were destroyed") );
|
||||
if( m_linkcount == 0 || --m_linkcount == 0 )
|
||||
wxASSERT_MSG( m_objcount == 0,
|
||||
_T("Library unloaded before all objects were destroyed") );
|
||||
|
||||
if ( --m_linkcount == 0 )
|
||||
{
|
||||
delete this;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -470,7 +497,7 @@ void wxPluginLibrary::UnregisterModules()
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// wxPluginLibrary
|
||||
// wxPluginManager
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
wxDLManifest* wxPluginManager::ms_manifest = NULL;
|
||||
@@ -479,49 +506,95 @@ wxDLManifest* wxPluginManager::ms_manifest = NULL;
|
||||
// Static accessors
|
||||
// ------------------------
|
||||
|
||||
wxPluginLibrary *wxPluginManager::LoadLibrary(const wxString &libname, int flags)
|
||||
wxPluginLibrary *
|
||||
wxPluginManager::LoadLibrary(const wxString &libname, int flags)
|
||||
{
|
||||
wxString realname(libname);
|
||||
|
||||
if( !(flags & wxDL_VERBATIM) )
|
||||
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();
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = new wxPluginLibrary( libname, flags );
|
||||
|
||||
if( entry->IsLoaded() )
|
||||
if ( entry->IsLoaded() )
|
||||
{
|
||||
ms_manifest->Put(realname, (wxObject*) entry);
|
||||
|
||||
wxLogTrace(_T("dll"),
|
||||
_T("LoadLibrary(%s): loaded ok."), realname.c_str());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCHECK_MSG( entry->UnrefLib(), 0,
|
||||
_T("Currently linked library is, ..not loaded??") );
|
||||
entry = 0;
|
||||
wxLogTrace(_T("dll"),
|
||||
_T("LoadLibrary(%s): failed to load."), realname.c_str());
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
bool wxPluginManager::UnloadLibrary(const wxString &libname)
|
||||
bool wxPluginManager::UnloadLibrary(const wxString& libname)
|
||||
{
|
||||
wxPluginLibrary *entry = (wxPluginLibrary*) ms_manifest->Get(libname);
|
||||
wxString realname = libname;
|
||||
|
||||
if( !entry )
|
||||
entry = (wxPluginLibrary*) ms_manifest->Get(libname + wxDynamicLibrary::GetDllExt());
|
||||
wxPluginLibrary *entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
||||
|
||||
if( entry )
|
||||
return entry->UnrefLib();
|
||||
if ( !entry )
|
||||
{
|
||||
realname += wxDynamicLibrary::GetDllExt();
|
||||
|
||||
wxLogDebug(_T("Attempt to Unlink library '%s' (which is not linked)."), libname.c_str());
|
||||
return FALSE;
|
||||
entry = (wxPluginLibrary*) ms_manifest->Get(realname);
|
||||
}
|
||||
|
||||
if ( !entry )
|
||||
{
|
||||
wxLogDebug(_T("Attempt to unload library '%s' which is not loaded."),
|
||||
libname.c_str());
|
||||
|
||||
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
|
||||
@@ -534,9 +607,9 @@ wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
|
||||
if( ((wxPluginLibrary*)node->GetData())->GetLibHandle() == handle )
|
||||
return (wxPluginLibrary*)node->GetData();
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#endif // WXWIN_COMPATIBILITY_2_2
|
||||
|
||||
// ------------------------
|
||||
// Class implementation
|
||||
@@ -574,19 +647,39 @@ void wxPluginManager::Unload()
|
||||
|
||||
wxDllType wxDllLoader::LoadLibrary(const wxString &name)
|
||||
{
|
||||
wxPluginLibrary *p = wxPluginManager::LoadLibrary(name, wxDL_DEFAULT | wxDL_VERBATIM);
|
||||
return p->GetLibHandle();
|
||||
wxPluginLibrary *p = wxPluginManager::LoadLibrary
|
||||
(
|
||||
name,
|
||||
wxDL_DEFAULT | wxDL_VERBATIM | wxDL_NOSHARE
|
||||
);
|
||||
|
||||
return p ? p->GetLibHandle() : 0;
|
||||
}
|
||||
|
||||
void wxDllLoader::UnloadLibrary(wxDllType handle)
|
||||
{
|
||||
wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(handle);
|
||||
|
||||
wxCHECK_RET( p, _T("Unloading a library not loaded with wxDllLoader?") );
|
||||
|
||||
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);
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
wxFAIL_MSG( _T("Using a library not loaded with wxDllLoader?") );
|
||||
|
||||
if ( success )
|
||||
*success = FALSE;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p->GetSymbol(name, success);
|
||||
}
|
||||
|
||||
@@ -594,4 +687,3 @@ void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *su
|
||||
|
||||
#endif // wxUSE_DYNAMIC_LOADER
|
||||
|
||||
// vi:sts=4:sw=4:et
|
||||
|
Reference in New Issue
Block a user