From 9e4fff33624721fa633cc328bb5b21c503101df2 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 19 Sep 2015 20:57:18 -0700 Subject: [PATCH] Add a state variable to CPlugin to indicate queue/list membership. --- core/logic/PluginSys.cpp | 31 +++++++++++++------ core/logic/PluginSys.h | 66 +++++++++++++++++----------------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index 131a99d9..7fc392eb 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -55,7 +55,7 @@ IdentityType_t g_PluginIdent = 0; CPlugin::CPlugin(const char *file) : m_serial(0), m_status(Plugin_Uncompiled), - m_WaitingToUnload(false), + m_state(PluginState::Unregistered), m_AddedLibraries(false), m_SilentFailure(false), m_FakeNativesMissing(false), @@ -978,11 +978,13 @@ void CPluginManager::LoadAutoPlugin(const char *plugin) void CPluginManager::AddPlugin(CPlugin *pPlugin) { - for (ListenerIter iter(m_listeners); !iter.done(); iter.next()) - (*iter)->OnPluginCreated(pPlugin); - m_plugins.append(pPlugin); m_LoadLookup.insert(pPlugin->GetFilename(), pPlugin); + + pPlugin->SetRegistered(); + + for (ListenerIter iter(m_listeners); !iter.done(); iter.next()) + (*iter)->OnPluginCreated(pPlugin); } void CPluginManager::LoadAll_SecondPass() @@ -1125,6 +1127,18 @@ bool CPlugin::ForEachRequiredLib(ke::Lambda callback) return true; } +void CPlugin::SetRegistered() +{ + assert(m_state == PluginState::Unregistered); + m_state = PluginState::Registered; +} + +void CPlugin::SetWaitingToUnload() +{ + assert(m_state == PluginState::Registered); + m_state = PluginState::WaitingToUnload; +} + void CPluginManager::LoadExtensions(CPlugin *pPlugin) { auto callback = [pPlugin] (const sp_pubvar_t *pubvar, const CPlugin::ExtVar& ext) -> bool @@ -1366,11 +1380,6 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin) bool CPluginManager::UnloadPlugin(IPlugin *plugin) { CPlugin *pPlugin = (CPlugin *)plugin; - - // If we're already in the unload queue, just wait. - if (pPlugin->WaitingToUnload()) - return false; - return ScheduleUnload(pPlugin); } @@ -1379,6 +1388,10 @@ bool CPluginManager::ScheduleUnload(CPlugin *pPlugin) // Should not be recursively removing. assert(m_plugins.contains(pPlugin)); + // If we're already in the unload queue, just wait. + if (pPlugin->State() == PluginState::WaitingToUnload) + return false; + IPluginContext *pContext = pPlugin->GetBaseContext(); if (pContext && pContext->IsInExec()) { ke::Lambda callback = [this, pPlugin]() { diff --git a/core/logic/PluginSys.h b/core/logic/PluginSys.h index 6a5c96bb..e5a1f175 100644 --- a/core/logic/PluginSys.h +++ b/core/logic/PluginSys.h @@ -75,6 +75,19 @@ enum APLRes APLRes_SilentFailure }; +// Plugin membership state. +enum class PluginState +{ + // The plugin has not yet been added to the global plugin list. + Unregistered, + + // The plugin is a member of the global plugin list. + Registered, + + // The plugin is waiting to be unloaded. + WaitingToUnload +}; + class CPlugin : public SMPlugin, public CNativeOwner @@ -134,60 +147,37 @@ public: // Evicts the plugin from memory and sets an error state. void EvictWithError(PluginStatus status, const char *error_fmt, ...); - /** - * Initializes the plugin's identity information - */ + // Initializes the plugin's identity information void InitIdentity(); - /** - * Calls the OnPluginLoad function, and sets any failed states if necessary. - * After invoking AskPluginLoad, its state is either Running or Failed. - */ + // Calls the OnPluginLoad function, and sets any failed states if necessary. + // After invoking AskPluginLoad, its state is either Running or Failed. APLRes AskPluginLoad(); - /** - * Calls the OnPluginStart function. - * NOTE: Valid pre-states are: Plugin_Created - * NOTE: Post-state will be Plugin_Running - */ + // Calls the OnPluginStart function. + // NOTE: Valid pre-states are: Plugin_Created + // NOTE: Post-state will be Plugin_Running void Call_OnPluginStart(); - - /** - * Calls the OnPluginEnd function. - */ void Call_OnPluginEnd(); - - /** - * Calls the OnAllPluginsLoaded function. - */ void Call_OnAllPluginsLoaded(); - - /** - * Calls the OnLibraryAdded function. - */ void Call_OnLibraryAdded(const char *lib); - /** - * Returns true if a plugin is usable. - */ + // Returns true if a plugin is usable. bool IsRunnable(); - /** - * Get languages info. - */ + // Get languages info. IPhraseCollection *GetPhrases(); + PluginState State() const { + return m_state; + } + void SetRegistered(); + void SetWaitingToUnload(); + public: // Returns true if the plugin was running, but is now invalid. bool WasRunning(); - bool WaitingToUnload() const { - return m_WaitingToUnload; - } - void SetWaitingToUnload() { - m_WaitingToUnload = true; - } - Handle_t GetMyHandle(); bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func); @@ -247,7 +237,7 @@ private: unsigned int m_serial; PluginStatus m_status; - bool m_WaitingToUnload; + PluginState m_state; bool m_AddedLibraries; // Statuses that are set during failure.