From 4f4903a05ef24e9e192bce064cb076063fdcbf90 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Mon, 14 Mar 2016 13:24:23 +0100 Subject: [PATCH] Don't try to call functions in paused plugins This avoids spam of "Plugin not runnable" exceptions on shutdown or plugin unload. When re/unloading a plugin which has other ones depending on it, like the adminmenu, It pauses the depending plugins putting them in an "Depends on plugin: %s" error state. ForwardSys doesn't remove them from the forward lists on pause, specially the global forwards, and still tries to call all the global forwards like OnPlayerRunCmd and OnLibraryAdded etc. on the paused plugins. Executing functions in paused runtimes has been ignored in the VM before introducing the "Exception" mechanism, but now they're all logged. This adds checks to make sure the plugin is runnable before calling a function. (Stolen from #438) --- core/logic/ForwardSys.cpp | 3 ++ core/logic/smn_database.cpp | 61 +++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/core/logic/ForwardSys.cpp b/core/logic/ForwardSys.cpp index 3ec59b04..f7932621 100644 --- a/core/logic/ForwardSys.cpp +++ b/core/logic/ForwardSys.cpp @@ -252,6 +252,9 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter) if (filter) filter->Preprocess(func, temp_info); + if (func->GetParentRuntime()->IsPaused()) + continue; + for (unsigned int i=0; iIsRunnable()) + return; + m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushString("Driver is unloading"); @@ -266,11 +269,14 @@ public: } } - m_pFunction->PushCell(m_MyHandle); - m_pFunction->PushCell(qh); - m_pFunction->PushString(qh == BAD_HANDLE ? error : ""); - m_pFunction->PushCell(m_Data); - m_pFunction->Execute(NULL); + if (m_pFunction->IsRunnable()) + { + m_pFunction->PushCell(m_MyHandle); + m_pFunction->PushCell(qh); + m_pFunction->PushString(qh == BAD_HANDLE ? error : ""); + m_pFunction->PushCell(m_Data); + m_pFunction->Execute(NULL); + } if (qh != BAD_HANDLE) { @@ -334,9 +340,11 @@ public: void CancelThinkPart() { if (m_pDatabase) - { m_pDatabase->Close(); - } + + if (!m_pFunction->IsRunnable()) + return; + if (m_ACM == ACM_Old) m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE); @@ -348,6 +356,13 @@ public: { Handle_t hndl = BAD_HANDLE; + if (!m_pFunction->IsRunnable()) + { + if (m_pDatabase) + m_pDatabase->Close(); + return; + } + if (m_pDatabase) { if ((hndl = g_DBMan.CreateHandle(DBHandle_Database, m_pDatabase, me->GetIdentity())) @@ -1659,12 +1674,15 @@ private: data[i] = txn_->entries[i].data; } - success_->PushCell(dbh); - success_->PushCell(data_); - success_->PushCell(txn_->entries.length()); - success_->PushArray(handles, results_.length()); - success_->PushArray(data, results_.length()); - success_->Execute(NULL); + if (success_->IsRunnable()) + { + success_->PushCell(dbh); + success_->PushCell(data_); + success_->PushCell(txn_->entries.length()); + success_->PushArray(handles, results_.length()); + success_->PushArray(data, results_.length()); + success_->Execute(NULL); + } // Cleanup. Note we clear results_, since freeing their handles will // call Destroy(), and we don't want to double-free in ~TTransactOp. @@ -1703,13 +1721,16 @@ public: db_->AddRef(); } - failure_->PushCell(dbh); - failure_->PushCell(data_); - failure_->PushCell(txn_->entries.length()); - failure_->PushString(error_.chars()); - failure_->PushCell(failIndex_); - failure_->PushArray(data, txn_->entries.length()); - failure_->Execute(NULL); + if (failure_->IsRunnable()) + { + failure_->PushCell(dbh); + failure_->PushCell(data_); + failure_->PushCell(txn_->entries.length()); + failure_->PushString(error_.chars()); + failure_->PushCell(failIndex_); + failure_->PushArray(data, txn_->entries.length()); + failure_->Execute(NULL); + } handlesys->FreeHandle(dbh, &sec); }