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 );
}
// 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)
};
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
: 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 )
{
RegisterModules();
}
else
- --m_count; // Flag us for deletion
+ --m_linkcount; // Flag us for deletion
}
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
// 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)
oldNode = node;
} while( node );
- --m_count; // Flag us for deletion
+ --m_linkcount; // Flag us for deletion
break;
}
}
if( entry )
{
- entry->Ref();
+ entry->RefLib();
}
else
{
}
else
{
- wxCHECK_MSG( !entry->Unref(), 0,
+ wxCHECK_MSG( !entry->UnrefLib(), 0,
_T("Currently linked library is, ..not loaded??") );
entry = 0;
}
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;
if( m_entry != 0 )
{
- m_entry->Ref();
+ m_entry->RefLib();
}
else
{
if( (wxDLManifestEntry*)node->GetData() == m_entry )
break;
- if( m_entry && m_entry->Unref() )
+ if( m_entry && m_entry->UnrefLib() )
delete node;
}