Don't use server commands to flush plugin unloads.

This commit is contained in:
David Anderson
2015-09-15 19:43:41 -07:00
parent 08cadcdda6
commit c36f80b93d
8 changed files with 135 additions and 17 deletions
+1
View File
@@ -80,6 +80,7 @@ binary.sources += [
'LibrarySys.cpp',
'RootConsoleMenu.cpp',
'CDataPack.cpp',
'frame_tasks.cpp',
]
if builder.target_platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
+15 -6
View File
@@ -43,6 +43,7 @@
#include "common_logic.h"
#include "Translator.h"
#include "Logger.h"
#include "frame_tasks.h"
#include <am-string.h>
#include <bridge/include/IVEngineServerBridge.h>
#include <bridge/include/CoreProvider.h>
@@ -54,6 +55,7 @@ IdentityType_t g_PluginIdent = 0;
CPlugin::CPlugin(const char *file)
: m_serial(0),
m_status(Plugin_Uncompiled),
m_WaitingToUnload(false),
m_SilentFailure(false),
m_FakeNativesMissing(false),
m_LibraryMissing(false),
@@ -1422,7 +1424,13 @@ void CPluginManager::TryRefreshDependencies(CPlugin *pPlugin)
bool CPluginManager::UnloadPlugin(IPlugin *plugin)
{
return ScheduleUnload((CPlugin *)plugin);
CPlugin *pPlugin = (CPlugin *)plugin;
// If we're already in the unload queue, just wait.
if (pPlugin->WaitingToUnload())
return false;
return ScheduleUnload(pPlugin);
}
bool CPluginManager::ScheduleUnload(CPlugin *pPlugin)
@@ -1431,11 +1439,12 @@ bool CPluginManager::ScheduleUnload(CPlugin *pPlugin)
assert(m_plugins.find(pPlugin) != m_plugins.end());
IPluginContext *pContext = pPlugin->GetBaseContext();
if (pContext && pContext->IsInExec())
{
char buffer[255];
ke::SafeSprintf(buffer, sizeof(buffer), "sm plugins unload %s\n", pPlugin->GetFilename());
engine->ServerCommand(buffer);
if (pContext && pContext->IsInExec()) {
ke::Lambda<void()> callback = [this, pPlugin]() {
this->ScheduleUnload(pPlugin);
};
pPlugin->SetWaitingToUnload();
ScheduleTaskForNextFrame(ke::Move(callback));
return false;
}
+12 -11
View File
@@ -222,29 +222,29 @@ public:
*/
IPhraseCollection *GetPhrases();
public:
/**
* Returns the modification time during last plugin load.
*/
// Returns the modification time during last plugin load.
time_t GetTimeStamp();
/**
* Returns the current modification time of the plugin file.
*/
// Returns the current modification time of the plugin file.
time_t GetFileTimeStamp();
/**
* 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 WaitingToUnload() const {
return m_WaitingToUnload;
}
void SetWaitingToUnload() {
m_WaitingToUnload = true;
}
Handle_t GetMyHandle();
bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
size_t GetConfigCount();
AutoConfig *GetConfig(size_t i);
inline void AddLibrary(const char *name)
{
inline void AddLibrary(const char *name) {
m_Libraries.push_back(name);
}
void LibraryActions(LibraryAction action);
@@ -260,6 +260,7 @@ private:
unsigned int m_serial;
PluginStatus m_status;
bool m_WaitingToUnload;
// Statuses that are set during failure.
bool m_SilentFailure;
+4
View File
@@ -51,6 +51,7 @@
#include "AdminCache.h"
#include "ProfileTools.h"
#include "Logger.h"
#include "frame_tasks.h"
#include "sprintf.h"
#include "LibrarySys.h"
#include "RootConsoleMenu.h"
@@ -137,6 +138,9 @@ public:
bool OnLogPrint(const char *msg) override {
return ::OnLogPrint(msg);
}
void OnThink(bool simulating) override {
RunScheduledFrameTasks(simulating);
}
} sProviderCallbackListener;
static sm_logic_t logic =
+55
View File
@@ -0,0 +1,55 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
// =============================================================================
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#include "frame_tasks.h"
#include <am-vector.h>
using namespace SourceMod;
ke::Vector<ke::Lambda<void()>> sNextTasks;
ke::Vector<ke::Lambda<void()>> sWorkTasks;
void
SourceMod::ScheduleTaskForNextFrame(ke::Lambda<void()>&& task)
{
sNextTasks.append(ke::Forward<decltype(task)>(task));
}
void
SourceMod::RunScheduledFrameTasks(bool simulating)
{
if (sNextTasks.empty())
return;
// Swap.
ke::Vector<ke::Lambda<void()>> temp(ke::Move(sNextTasks));
sNextTasks = ke::Move(sWorkTasks);
sWorkTasks = ke::Move(temp);
for (size_t i = 0; i < sWorkTasks.length(); i++)
sWorkTasks[i]();
sWorkTasks.clear();
}
+40
View File
@@ -0,0 +1,40 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
// =============================================================================
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _include_sourcemod_logic_frame_tasks_h_
#define _include_sourcemod_logic_frame_tasks_h_
#include <am-function.h>
namespace SourceMod {
void ScheduleTaskForNextFrame(ke::Lambda<void()>&& task);
void RunScheduledFrameTasks(bool simulating);
}
#endif // _include_sourcemod_logic_frame_tasks_h_