From 0b131d6864549b419e6aa5ae5180fc74704f0828 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Sun, 13 Jul 2014 13:56:47 +0200 Subject: [PATCH] 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. --- core/logic/PluginSys.cpp | 31 +++++++++++++++++++------------ core/logic/smn_core.cpp | 8 ++++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index c53d4fe3..a22544df 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -195,15 +195,20 @@ 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); smcore.FormatArgs(m_errormsg, sizeof(m_errormsg), error_fmt, ap); @@ -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); } } } diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index 50eb0e5d..c595ebab 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -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); } } @@ -774,4 +774,4 @@ REGISTER_NATIVES(coreNatives) {"LoadFromAddress", LoadFromAddress}, {"StoreToAddress", StoreToAddress}, {NULL, NULL}, -}; \ No newline at end of file +};