From 7c1e2b44010c1a8dcf9bd26c390d1991f6f7e64f Mon Sep 17 00:00:00 2001 From: Ron Lee Date: Thu, 20 Dec 2001 12:06:11 +0000 Subject: [PATCH] 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 --- include/wx/dynload.h | 50 +++++++++++++++++++++++++++++------------- include/wx/object.h | 4 ++-- src/common/dynload.cpp | 29 ++++++++++++++++-------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/include/wx/dynload.h b/include/wx/dynload.h index fd813044a4..2678f23dbe 100644 --- a/include/wx/dynload.h +++ b/include/wx/dynload.h @@ -137,14 +137,33 @@ public: wxDLManifestEntry( const wxString &libname ); ~wxDLManifestEntry(); - wxDLManifestEntry *Ref() { ++m_count; return this; } - bool Unref() { return (m_count-- < 2) ? (delete this, TRUE) : FALSE; } + wxDLManifestEntry *RefLib() { ++m_linkcount; return this; } + bool UnrefLib(); + + // 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_count > 0; } + 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) + 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 ); } @@ -153,17 +172,18 @@ private: // Order of these three *is* important, do not change it - wxClassInfo *m_before; // sm_first before loading this lib - wxDllType m_handle; // Handle from dlopen. - wxClassInfo *m_after; // ..and after. + wxClassInfo *m_before; // sm_first before loading this lib + wxDllType m_handle; // Handle from dlopen. + wxClassInfo *m_after; // ..and after. - size_t m_count; // Ref count of Link and Create calls. - wxModuleList m_wxmodules; // any wxModules that we initialised. + 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. - void UpdateClassInfo(); // Update the wxClassInfo table - void RestoreClassInfo(); // Restore the original wxClassInfo state. - void RegisterModules(); // Init any wxModules in the lib. - void UnregisterModules(); // Cleanup any wxModules we installed. + void UpdateClassInfo(); // Update the wxClassInfo table + void RestoreClassInfo(); // Restore the original wxClassInfo state. + void RegisterModules(); // Init any wxModules in the lib. + void UnregisterModules(); // Cleanup any wxModules we installed. DECLARE_NO_COPY_CLASS(wxDLManifestEntry) }; diff --git a/include/wx/object.h b/include/wx/object.h index e1ed101a37..69ad1b9f88 100644 --- a/include/wx/object.h +++ b/include/wx/object.h @@ -216,11 +216,11 @@ name##PluginSentinel m_pluginsentinel; const wxString name::name##PluginSentinel::sm_className(#name); \ name::name##PluginSentinel::name##PluginSentinel() { \ wxDLManifestEntry *e = (wxDLManifestEntry*) wxDLManifestEntry::ms_classes.Get(#name); \ - if( e != 0 ) { e->Ref(); } \ + if( e != 0 ) { e->RefObj(); } \ } \ name::name##PluginSentinel::~##name##PluginSentinel() { \ 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 diff --git a/src/common/dynload.cpp b/src/common/dynload.cpp index e4d3887695..298b362690 100644 --- a/src/common/dynload.cpp +++ b/src/common/dynload.cpp @@ -267,7 +267,8 @@ wxDLManifestEntry::wxDLManifestEntry( const wxString &libname ) : m_before(wxClassInfo::sm_first) , m_handle(wxDllLoader::LoadLibrary( libname )) , m_after(wxClassInfo::sm_first) - , m_count(1) + , m_linkcount(1) + , m_objcount(0) { if( m_handle != 0 ) { @@ -275,7 +276,7 @@ wxDLManifestEntry::wxDLManifestEntry( const wxString &libname ) RegisterModules(); } else - --m_count; // Flag us for deletion + --m_linkcount; // Flag us for deletion } wxDLManifestEntry::~wxDLManifestEntry() @@ -286,6 +287,16 @@ wxDLManifestEntry::~wxDLManifestEntry() 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 @@ -362,7 +373,7 @@ void wxDLManifestEntry::RegisterModules() // 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. - wxASSERT_MSG( m_count == 1, + wxASSERT_MSG( m_linkcount == 1, _T("RegisterModules should only be called for the first load") ); for(wxClassInfo *info = m_after; info != m_before; info = info->m_next) @@ -401,7 +412,7 @@ void wxDLManifestEntry::RegisterModules() oldNode = node; } while( node ); - --m_count; // Flag us for deletion + --m_linkcount; // Flag us for deletion break; } } @@ -437,7 +448,7 @@ wxDLManifestEntry *wxDynamicLibrary::Link(const wxString &libname) if( entry ) { - entry->Ref(); + entry->RefLib(); } else { @@ -449,7 +460,7 @@ wxDLManifestEntry *wxDynamicLibrary::Link(const wxString &libname) } else { - wxCHECK_MSG( !entry->Unref(), 0, + wxCHECK_MSG( !entry->UnrefLib(), 0, _T("Currently linked library is, ..not loaded??") ); entry = 0; } @@ -462,7 +473,7 @@ bool wxDynamicLibrary::Unlink(const wxString &libname) wxDLManifestEntry *entry = (wxDLManifestEntry*) ms_manifest.Get(libname); if( entry ) - return entry->Unref(); + return entry->UnrefLib(); wxLogDebug(_T("Attempt to Unlink library '%s' (which is not linked)."), libname.c_str()); return 0; @@ -478,7 +489,7 @@ wxDynamicLibrary::wxDynamicLibrary(const wxString &libname) if( m_entry != 0 ) { - m_entry->Ref(); + m_entry->RefLib(); } else { @@ -500,7 +511,7 @@ wxDynamicLibrary::~wxDynamicLibrary() if( (wxDLManifestEntry*)node->GetData() == m_entry ) break; - if( m_entry && m_entry->Unref() ) + if( m_entry && m_entry->UnrefLib() ) delete node; } -- 2.45.2