reimplemented sanity checks that were lost/broken in the regrettably
far to hasty last minute pushmepullyou api changes. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13131 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -137,10 +137,29 @@ public:
|
|||||||
wxDLManifestEntry( const wxString &libname );
|
wxDLManifestEntry( const wxString &libname );
|
||||||
~wxDLManifestEntry();
|
~wxDLManifestEntry();
|
||||||
|
|
||||||
wxDLManifestEntry *Ref() { ++m_count; return this; }
|
wxDLManifestEntry *RefLib() { ++m_linkcount; return this; }
|
||||||
bool Unref() { return (m_count-- < 2) ? (delete this, TRUE) : FALSE; }
|
bool UnrefLib();
|
||||||
|
|
||||||
bool IsLoaded() const { return m_count > 0; }
|
// These two are called by the PluginSentinel on (PLUGGABLE) object
|
||||||
|
// creation/destruction. There is usually no reason for the user to
|
||||||
|
// call them directly. We have to separate this from the link count,
|
||||||
|
// since the two are not interchangeable.
|
||||||
|
|
||||||
|
// FIXME: for even better debugging PluginSentinel should register
|
||||||
|
// the name of the class created too, then we can state
|
||||||
|
// exactly which object was not destroyed which may be
|
||||||
|
// difficult to find otherwise. Also this code should
|
||||||
|
// probably only be active in DEBUG mode, but let's just
|
||||||
|
// get it right first.
|
||||||
|
|
||||||
|
void RefObj() { ++m_objcount; }
|
||||||
|
void UnrefObj()
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( m_objcount > 0, _T("Too many objects deleted??") );
|
||||||
|
--m_objcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLoaded() const { return m_linkcount > 0; }
|
||||||
|
|
||||||
wxDllType GetLinkHandle() const { return m_handle; }
|
wxDllType GetLinkHandle() const { return m_handle; }
|
||||||
wxDllType GetProgramHandle() const { return wxDllLoader::GetProgramHandle(); }
|
wxDllType GetProgramHandle() const { return wxDllLoader::GetProgramHandle(); }
|
||||||
@@ -157,7 +176,8 @@ private:
|
|||||||
wxDllType m_handle; // Handle from dlopen.
|
wxDllType m_handle; // Handle from dlopen.
|
||||||
wxClassInfo *m_after; // ..and after.
|
wxClassInfo *m_after; // ..and after.
|
||||||
|
|
||||||
size_t m_count; // Ref count of Link and Create calls.
|
size_t m_linkcount; // Ref count of library link calls
|
||||||
|
size_t m_objcount; // ..and (pluggable) object instantiations.
|
||||||
wxModuleList m_wxmodules; // any wxModules that we initialised.
|
wxModuleList m_wxmodules; // any wxModules that we initialised.
|
||||||
|
|
||||||
void UpdateClassInfo(); // Update the wxClassInfo table
|
void UpdateClassInfo(); // Update the wxClassInfo table
|
||||||
|
@@ -216,11 +216,11 @@ name##PluginSentinel m_pluginsentinel;
|
|||||||
const wxString name::name##PluginSentinel::sm_className(#name); \
|
const wxString name::name##PluginSentinel::sm_className(#name); \
|
||||||
name::name##PluginSentinel::name##PluginSentinel() { \
|
name::name##PluginSentinel::name##PluginSentinel() { \
|
||||||
wxDLManifestEntry *e = (wxDLManifestEntry*) wxDLManifestEntry::ms_classes.Get(#name); \
|
wxDLManifestEntry *e = (wxDLManifestEntry*) wxDLManifestEntry::ms_classes.Get(#name); \
|
||||||
if( e != 0 ) { e->Ref(); } \
|
if( e != 0 ) { e->RefObj(); } \
|
||||||
} \
|
} \
|
||||||
name::name##PluginSentinel::~##name##PluginSentinel() { \
|
name::name##PluginSentinel::~##name##PluginSentinel() { \
|
||||||
wxDLManifestEntry *e = (wxDLManifestEntry*) wxDLManifestEntry::ms_classes.Get(#name); \
|
wxDLManifestEntry *e = (wxDLManifestEntry*) wxDLManifestEntry::ms_classes.Get(#name); \
|
||||||
if( e != 0 ) { wxCHECK_RET( !e->Unref(), _T("premature library unlinking") ); } \
|
if( e != 0 ) { e->UnrefObj(); } \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@@ -267,7 +267,8 @@ wxDLManifestEntry::wxDLManifestEntry( const wxString &libname )
|
|||||||
: m_before(wxClassInfo::sm_first)
|
: m_before(wxClassInfo::sm_first)
|
||||||
, m_handle(wxDllLoader::LoadLibrary( libname ))
|
, m_handle(wxDllLoader::LoadLibrary( libname ))
|
||||||
, m_after(wxClassInfo::sm_first)
|
, m_after(wxClassInfo::sm_first)
|
||||||
, m_count(1)
|
, m_linkcount(1)
|
||||||
|
, m_objcount(0)
|
||||||
{
|
{
|
||||||
if( m_handle != 0 )
|
if( m_handle != 0 )
|
||||||
{
|
{
|
||||||
@@ -275,7 +276,7 @@ wxDLManifestEntry::wxDLManifestEntry( const wxString &libname )
|
|||||||
RegisterModules();
|
RegisterModules();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
--m_count; // Flag us for deletion
|
--m_linkcount; // Flag us for deletion
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDLManifestEntry::~wxDLManifestEntry()
|
wxDLManifestEntry::~wxDLManifestEntry()
|
||||||
@@ -286,6 +287,16 @@ wxDLManifestEntry::~wxDLManifestEntry()
|
|||||||
wxDllLoader::UnloadLibrary(m_handle);
|
wxDllLoader::UnloadLibrary(m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxDLManifestEntry::UnrefLib()
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( m_objcount == 0, _T("Library unloaded before all objects were destroyed") );
|
||||||
|
if( m_linkcount == 0 || --m_linkcount == 0 )
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Private methods
|
// Private methods
|
||||||
@@ -362,7 +373,7 @@ void wxDLManifestEntry::RegisterModules()
|
|||||||
// the library is. We do have to keep a copy of the module's pointer
|
// the library is. We do have to keep a copy of the module's pointer
|
||||||
// though, as there is currently no way to Unregister it without it.
|
// though, as there is currently no way to Unregister it without it.
|
||||||
|
|
||||||
wxASSERT_MSG( m_count == 1,
|
wxASSERT_MSG( m_linkcount == 1,
|
||||||
_T("RegisterModules should only be called for the first load") );
|
_T("RegisterModules should only be called for the first load") );
|
||||||
|
|
||||||
for(wxClassInfo *info = m_after; info != m_before; info = info->m_next)
|
for(wxClassInfo *info = m_after; info != m_before; info = info->m_next)
|
||||||
@@ -401,7 +412,7 @@ void wxDLManifestEntry::RegisterModules()
|
|||||||
oldNode = node;
|
oldNode = node;
|
||||||
} while( node );
|
} while( node );
|
||||||
|
|
||||||
--m_count; // Flag us for deletion
|
--m_linkcount; // Flag us for deletion
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -437,7 +448,7 @@ wxDLManifestEntry *wxDynamicLibrary::Link(const wxString &libname)
|
|||||||
|
|
||||||
if( entry )
|
if( entry )
|
||||||
{
|
{
|
||||||
entry->Ref();
|
entry->RefLib();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -449,7 +460,7 @@ wxDLManifestEntry *wxDynamicLibrary::Link(const wxString &libname)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( !entry->Unref(), 0,
|
wxCHECK_MSG( !entry->UnrefLib(), 0,
|
||||||
_T("Currently linked library is, ..not loaded??") );
|
_T("Currently linked library is, ..not loaded??") );
|
||||||
entry = 0;
|
entry = 0;
|
||||||
}
|
}
|
||||||
@@ -462,7 +473,7 @@ bool wxDynamicLibrary::Unlink(const wxString &libname)
|
|||||||
wxDLManifestEntry *entry = (wxDLManifestEntry*) ms_manifest.Get(libname);
|
wxDLManifestEntry *entry = (wxDLManifestEntry*) ms_manifest.Get(libname);
|
||||||
|
|
||||||
if( entry )
|
if( entry )
|
||||||
return entry->Unref();
|
return entry->UnrefLib();
|
||||||
|
|
||||||
wxLogDebug(_T("Attempt to Unlink library '%s' (which is not linked)."), libname.c_str());
|
wxLogDebug(_T("Attempt to Unlink library '%s' (which is not linked)."), libname.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
@@ -478,7 +489,7 @@ wxDynamicLibrary::wxDynamicLibrary(const wxString &libname)
|
|||||||
|
|
||||||
if( m_entry != 0 )
|
if( m_entry != 0 )
|
||||||
{
|
{
|
||||||
m_entry->Ref();
|
m_entry->RefLib();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -500,7 +511,7 @@ wxDynamicLibrary::~wxDynamicLibrary()
|
|||||||
if( (wxDLManifestEntry*)node->GetData() == m_entry )
|
if( (wxDLManifestEntry*)node->GetData() == m_entry )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( m_entry && m_entry->Unref() )
|
if( m_entry && m_entry->UnrefLib() )
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user