Add a state variable to CPlugin to indicate queue/list membership.

This commit is contained in:
David Anderson 2015-09-19 20:57:18 -07:00
parent 7cc911ae58
commit 9e4fff3362
2 changed files with 50 additions and 47 deletions

View File

@ -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<bool(const char *)> 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<void()> callback = [this, pPlugin]() {

View File

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