Add a state variable to CPlugin to indicate queue/list membership.
This commit is contained in:
parent
7cc911ae58
commit
9e4fff3362
@ -55,7 +55,7 @@ IdentityType_t g_PluginIdent = 0;
|
|||||||
CPlugin::CPlugin(const char *file)
|
CPlugin::CPlugin(const char *file)
|
||||||
: m_serial(0),
|
: m_serial(0),
|
||||||
m_status(Plugin_Uncompiled),
|
m_status(Plugin_Uncompiled),
|
||||||
m_WaitingToUnload(false),
|
m_state(PluginState::Unregistered),
|
||||||
m_AddedLibraries(false),
|
m_AddedLibraries(false),
|
||||||
m_SilentFailure(false),
|
m_SilentFailure(false),
|
||||||
m_FakeNativesMissing(false),
|
m_FakeNativesMissing(false),
|
||||||
@ -978,11 +978,13 @@ void CPluginManager::LoadAutoPlugin(const char *plugin)
|
|||||||
|
|
||||||
void CPluginManager::AddPlugin(CPlugin *pPlugin)
|
void CPluginManager::AddPlugin(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
for (ListenerIter iter(m_listeners); !iter.done(); iter.next())
|
|
||||||
(*iter)->OnPluginCreated(pPlugin);
|
|
||||||
|
|
||||||
m_plugins.append(pPlugin);
|
m_plugins.append(pPlugin);
|
||||||
m_LoadLookup.insert(pPlugin->GetFilename(), 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()
|
void CPluginManager::LoadAll_SecondPass()
|
||||||
@ -1125,6 +1127,18 @@ bool CPlugin::ForEachRequiredLib(ke::Lambda<bool(const char *)> callback)
|
|||||||
return true;
|
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)
|
void CPluginManager::LoadExtensions(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
auto callback = [pPlugin] (const sp_pubvar_t *pubvar, const CPlugin::ExtVar& ext) -> bool
|
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)
|
bool CPluginManager::UnloadPlugin(IPlugin *plugin)
|
||||||
{
|
{
|
||||||
CPlugin *pPlugin = (CPlugin *)plugin;
|
CPlugin *pPlugin = (CPlugin *)plugin;
|
||||||
|
|
||||||
// If we're already in the unload queue, just wait.
|
|
||||||
if (pPlugin->WaitingToUnload())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return ScheduleUnload(pPlugin);
|
return ScheduleUnload(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1379,6 +1388,10 @@ bool CPluginManager::ScheduleUnload(CPlugin *pPlugin)
|
|||||||
// Should not be recursively removing.
|
// Should not be recursively removing.
|
||||||
assert(m_plugins.contains(pPlugin));
|
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();
|
IPluginContext *pContext = pPlugin->GetBaseContext();
|
||||||
if (pContext && pContext->IsInExec()) {
|
if (pContext && pContext->IsInExec()) {
|
||||||
ke::Lambda<void()> callback = [this, pPlugin]() {
|
ke::Lambda<void()> callback = [this, pPlugin]() {
|
||||||
|
@ -75,6 +75,19 @@ enum APLRes
|
|||||||
APLRes_SilentFailure
|
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 :
|
class CPlugin :
|
||||||
public SMPlugin,
|
public SMPlugin,
|
||||||
public CNativeOwner
|
public CNativeOwner
|
||||||
@ -134,60 +147,37 @@ public:
|
|||||||
// Evicts the plugin from memory and sets an error state.
|
// Evicts the plugin from memory and sets an error state.
|
||||||
void EvictWithError(PluginStatus status, const char *error_fmt, ...);
|
void EvictWithError(PluginStatus status, const char *error_fmt, ...);
|
||||||
|
|
||||||
/**
|
// Initializes the plugin's identity information
|
||||||
* Initializes the plugin's identity information
|
|
||||||
*/
|
|
||||||
void InitIdentity();
|
void InitIdentity();
|
||||||
|
|
||||||
/**
|
// Calls the OnPluginLoad function, and sets any failed states if necessary.
|
||||||
* Calls the OnPluginLoad function, and sets any failed states if necessary.
|
// After invoking AskPluginLoad, its state is either Running or Failed.
|
||||||
* After invoking AskPluginLoad, its state is either Running or Failed.
|
|
||||||
*/
|
|
||||||
APLRes AskPluginLoad();
|
APLRes AskPluginLoad();
|
||||||
|
|
||||||
/**
|
// Calls the OnPluginStart function.
|
||||||
* Calls the OnPluginStart function.
|
// NOTE: Valid pre-states are: Plugin_Created
|
||||||
* NOTE: Valid pre-states are: Plugin_Created
|
// NOTE: Post-state will be Plugin_Running
|
||||||
* NOTE: Post-state will be Plugin_Running
|
|
||||||
*/
|
|
||||||
void Call_OnPluginStart();
|
void Call_OnPluginStart();
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the OnPluginEnd function.
|
|
||||||
*/
|
|
||||||
void Call_OnPluginEnd();
|
void Call_OnPluginEnd();
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the OnAllPluginsLoaded function.
|
|
||||||
*/
|
|
||||||
void Call_OnAllPluginsLoaded();
|
void Call_OnAllPluginsLoaded();
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the OnLibraryAdded function.
|
|
||||||
*/
|
|
||||||
void Call_OnLibraryAdded(const char *lib);
|
void Call_OnLibraryAdded(const char *lib);
|
||||||
|
|
||||||
/**
|
// Returns true if a plugin is usable.
|
||||||
* Returns true if a plugin is usable.
|
|
||||||
*/
|
|
||||||
bool IsRunnable();
|
bool IsRunnable();
|
||||||
|
|
||||||
/**
|
// Get languages info.
|
||||||
* Get languages info.
|
|
||||||
*/
|
|
||||||
IPhraseCollection *GetPhrases();
|
IPhraseCollection *GetPhrases();
|
||||||
|
|
||||||
|
PluginState State() const {
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
void SetRegistered();
|
||||||
|
void SetWaitingToUnload();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns true if the plugin was running, but is now invalid.
|
// Returns true if the plugin was running, but is now invalid.
|
||||||
bool WasRunning();
|
bool WasRunning();
|
||||||
|
|
||||||
bool WaitingToUnload() const {
|
|
||||||
return m_WaitingToUnload;
|
|
||||||
}
|
|
||||||
void SetWaitingToUnload() {
|
|
||||||
m_WaitingToUnload = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle_t GetMyHandle();
|
Handle_t GetMyHandle();
|
||||||
|
|
||||||
bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
||||||
@ -247,7 +237,7 @@ private:
|
|||||||
unsigned int m_serial;
|
unsigned int m_serial;
|
||||||
|
|
||||||
PluginStatus m_status;
|
PluginStatus m_status;
|
||||||
bool m_WaitingToUnload;
|
PluginState m_state;
|
||||||
bool m_AddedLibraries;
|
bool m_AddedLibraries;
|
||||||
|
|
||||||
// Statuses that are set during failure.
|
// Statuses that are set during failure.
|
||||||
|
Loading…
Reference in New Issue
Block a user