Pause dependent plugins on SetFailState (bug 6120)
When a plugin calls SetFailState it is paused and all natives it registered are unavailable. Other plugins, which depend on those natives keep running and error whenever they try to call those natives. This correctly sets the dependent plugins to an error state as if the plugin which called SetFailState was unloaded.
This commit is contained in:
parent
abb8d8447f
commit
0b131d6864
@ -195,14 +195,19 @@ IPluginRuntime *CPlugin::GetRuntime()
|
||||
|
||||
void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
|
||||
{
|
||||
PluginStatus old_status = m_status;
|
||||
m_status = status;
|
||||
|
||||
if (old_status == Plugin_Running)
|
||||
if (m_status == Plugin_Running)
|
||||
{
|
||||
/* Tell everyone we're now paused */
|
||||
g_PluginSys._SetPauseState(this, true);
|
||||
SetPauseState(true);
|
||||
/* If we won't recover from this error, drop everything and pause dependent plugins too! */
|
||||
if (status == Plugin_Failed)
|
||||
{
|
||||
DropEverything();
|
||||
}
|
||||
}
|
||||
|
||||
/* SetPauseState sets the status to Plugin_Paused, but we might want to see some other status set. */
|
||||
m_status = status;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, error_fmt);
|
||||
@ -531,7 +536,8 @@ bool CPlugin::SetPauseState(bool paused)
|
||||
if (paused && GetStatus() != Plugin_Running)
|
||||
{
|
||||
return false;
|
||||
} else if (!paused && GetStatus() != Plugin_Paused) {
|
||||
}
|
||||
else if (!paused && GetStatus() != Plugin_Paused && GetStatus() != Plugin_Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -539,6 +545,12 @@ bool CPlugin::SetPauseState(bool paused)
|
||||
{
|
||||
LibraryActions(LibraryAction_Removed);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set to running again BEFORE trying to call OnPluginPauseChange ;)
|
||||
m_status = Plugin_Running;
|
||||
m_pRuntime->SetPauseState(false);
|
||||
}
|
||||
|
||||
IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("OnPluginPauseChange");
|
||||
if (pFunction)
|
||||
@ -552,9 +564,6 @@ bool CPlugin::SetPauseState(bool paused)
|
||||
{
|
||||
m_status = Plugin_Paused;
|
||||
m_pRuntime->SetPauseState(true);
|
||||
} else {
|
||||
m_status = Plugin_Running;
|
||||
m_pRuntime->SetPauseState(false);
|
||||
}
|
||||
|
||||
g_PluginSys._SetPauseState(this, paused);
|
||||
@ -1496,11 +1505,9 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
|
||||
if (pPlugin->GetStatus() == Plugin_Error)
|
||||
{
|
||||
/* If we got here, all natives are okay again! */
|
||||
pPlugin->m_status = Plugin_Running;
|
||||
if (pPlugin->m_pRuntime->IsPaused())
|
||||
{
|
||||
pPlugin->m_pRuntime->SetPauseState(false);
|
||||
_SetPauseState(pPlugin, false);
|
||||
pPlugin->SetPauseState(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (params[0] == 1)
|
||||
{
|
||||
pPlugin->SetErrorState(Plugin_Error, "%s", str);
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", str);
|
||||
|
||||
return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", str);
|
||||
}
|
||||
@ -391,12 +391,12 @@ static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
||||
{
|
||||
pPlugin->SetErrorState(Plugin_Error, "%s", str);
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", str);
|
||||
return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "Formatting error (%s)", str);
|
||||
}
|
||||
else
|
||||
{
|
||||
pPlugin->SetErrorState(Plugin_Error, "%s", buffer);
|
||||
pPlugin->SetErrorState(Plugin_Failed, "%s", buffer);
|
||||
return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user