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)
This commit is contained in:
Peace-Maker 2016-03-14 13:24:23 +01:00
parent f7bb423f06
commit 4f4903a05e
2 changed files with 44 additions and 20 deletions

View File

@ -252,6 +252,9 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
if (filter) if (filter)
filter->Preprocess(func, temp_info); filter->Preprocess(func, temp_info);
if (func->GetParentRuntime()->IsPaused())
continue;
for (unsigned int i=0; i<num_params; i++) for (unsigned int i=0; i<num_params; i++)
{ {
int err = SP_ERROR_PARAM; int err = SP_ERROR_PARAM;

View File

@ -236,6 +236,9 @@ public:
} }
void CancelThinkPart() void CancelThinkPart()
{ {
if (!m_pFunction->IsRunnable())
return;
m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushString("Driver is unloading"); m_pFunction->PushString("Driver is unloading");
@ -266,11 +269,14 @@ public:
} }
} }
m_pFunction->PushCell(m_MyHandle); if (m_pFunction->IsRunnable())
m_pFunction->PushCell(qh); {
m_pFunction->PushString(qh == BAD_HANDLE ? error : ""); m_pFunction->PushCell(m_MyHandle);
m_pFunction->PushCell(m_Data); m_pFunction->PushCell(qh);
m_pFunction->Execute(NULL); m_pFunction->PushString(qh == BAD_HANDLE ? error : "");
m_pFunction->PushCell(m_Data);
m_pFunction->Execute(NULL);
}
if (qh != BAD_HANDLE) if (qh != BAD_HANDLE)
{ {
@ -334,9 +340,11 @@ public:
void CancelThinkPart() void CancelThinkPart()
{ {
if (m_pDatabase) if (m_pDatabase)
{
m_pDatabase->Close(); m_pDatabase->Close();
}
if (!m_pFunction->IsRunnable())
return;
if (m_ACM == ACM_Old) if (m_ACM == ACM_Old)
m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE);
@ -348,6 +356,13 @@ public:
{ {
Handle_t hndl = BAD_HANDLE; Handle_t hndl = BAD_HANDLE;
if (!m_pFunction->IsRunnable())
{
if (m_pDatabase)
m_pDatabase->Close();
return;
}
if (m_pDatabase) if (m_pDatabase)
{ {
if ((hndl = g_DBMan.CreateHandle(DBHandle_Database, m_pDatabase, me->GetIdentity())) if ((hndl = g_DBMan.CreateHandle(DBHandle_Database, m_pDatabase, me->GetIdentity()))
@ -1659,12 +1674,15 @@ private:
data[i] = txn_->entries[i].data; data[i] = txn_->entries[i].data;
} }
success_->PushCell(dbh); if (success_->IsRunnable())
success_->PushCell(data_); {
success_->PushCell(txn_->entries.length()); success_->PushCell(dbh);
success_->PushArray(handles, results_.length()); success_->PushCell(data_);
success_->PushArray(data, results_.length()); success_->PushCell(txn_->entries.length());
success_->Execute(NULL); success_->PushArray(handles, results_.length());
success_->PushArray(data, results_.length());
success_->Execute(NULL);
}
// Cleanup. Note we clear results_, since freeing their handles will // Cleanup. Note we clear results_, since freeing their handles will
// call Destroy(), and we don't want to double-free in ~TTransactOp. // call Destroy(), and we don't want to double-free in ~TTransactOp.
@ -1703,13 +1721,16 @@ public:
db_->AddRef(); db_->AddRef();
} }
failure_->PushCell(dbh); if (failure_->IsRunnable())
failure_->PushCell(data_); {
failure_->PushCell(txn_->entries.length()); failure_->PushCell(dbh);
failure_->PushString(error_.chars()); failure_->PushCell(data_);
failure_->PushCell(failIndex_); failure_->PushCell(txn_->entries.length());
failure_->PushArray(data, txn_->entries.length()); failure_->PushString(error_.chars());
failure_->Execute(NULL); failure_->PushCell(failIndex_);
failure_->PushArray(data, txn_->entries.length());
failure_->Execute(NULL);
}
handlesys->FreeHandle(dbh, &sec); handlesys->FreeHandle(dbh, &sec);
} }