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:
Ron Lee
2001-12-20 12:06:11 +00:00
parent 1c469f7f4e
commit 7c1e2b4401
3 changed files with 57 additions and 26 deletions

View File

@@ -137,14 +137,33 @@ 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.
wxDllType GetLinkHandle() const { return m_handle; } // FIXME: for even better debugging PluginSentinel should register
wxDllType GetProgramHandle() const { return wxDllLoader::GetProgramHandle(); } // the name of the class created too, then we can state
void *GetSymbol(const wxString &symbol, bool *success = 0) // 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 GetProgramHandle() const { return wxDllLoader::GetProgramHandle(); }
void *GetSymbol(const wxString &symbol, bool *success = 0)
{ {
return wxDllLoader::GetSymbol( m_handle, symbol, success ); return wxDllLoader::GetSymbol( m_handle, symbol, success );
} }
@@ -153,17 +172,18 @@ private:
// Order of these three *is* important, do not change it // Order of these three *is* important, do not change it
wxClassInfo *m_before; // sm_first before loading this lib wxClassInfo *m_before; // sm_first before loading this lib
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
wxModuleList m_wxmodules; // any wxModules that we initialised. size_t m_objcount; // ..and (pluggable) object instantiations.
wxModuleList m_wxmodules; // any wxModules that we initialised.
void UpdateClassInfo(); // Update the wxClassInfo table void UpdateClassInfo(); // Update the wxClassInfo table
void RestoreClassInfo(); // Restore the original wxClassInfo state. void RestoreClassInfo(); // Restore the original wxClassInfo state.
void RegisterModules(); // Init any wxModules in the lib. void RegisterModules(); // Init any wxModules in the lib.
void UnregisterModules(); // Cleanup any wxModules we installed. void UnregisterModules(); // Cleanup any wxModules we installed.
DECLARE_NO_COPY_CLASS(wxDLManifestEntry) DECLARE_NO_COPY_CLASS(wxDLManifestEntry)
}; };

View File

@@ -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

View File

@@ -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;
} }