From d3eb1a77d7ee2f924ab0fd6e5642fb328e4209d8 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 26 Nov 2015 15:10:00 +0100 Subject: core_reloadmodule Allow modules to save and restore their own data when reloading another mod --- include/modules/reload.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 include/modules/reload.h (limited to 'include/modules') diff --git a/include/modules/reload.h b/include/modules/reload.h new file mode 100644 index 000000000..6ee30c45e --- /dev/null +++ b/include/modules/reload.h @@ -0,0 +1,80 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2015 Attila Molnar + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * 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 . + */ + + +#pragma once + +#include "event.h" + +namespace ReloadModule +{ + class EventListener; + class DataKeeper; + + /** Container for data saved by modules before another module is reloaded. + */ + class CustomData + { + struct Data + { + EventListener* handler; + void* data; + Data(EventListener* Handler, void* moddata) : handler(Handler), data(moddata) { } + }; + typedef std::vector List; + List list; + + public: + /** Add data to the saved state of a module. + * The provided handler's OnReloadModuleRestore() method will be called when the reload is done with the pointer + * provided. + * @param handler Handler for restoring the data + * @param data Pointer to the data, will be passed back to the provided handler's OnReloadModuleRestore() after the + * reload finishes + */ + void add(EventListener* handler, void* data) + { + list.push_back(Data(handler, data)); + } + + friend class DataKeeper; + }; + + class EventListener : public Events::ModuleEventListener + { + public: + EventListener(Module* mod) + : ModuleEventListener(mod, "event/reloadmodule") + { + } + + /** Called whenever a module is about to be reloaded. Use this event to save data related to the module that you want + * to be restored after the reload. + * @param mod Module to be reloaded + * @param cd CustomData instance that can store your data once. + */ + virtual void OnReloadModuleSave(Module* mod, CustomData& cd) = 0; + + /** Restore data after a reload. Only called if data was added in OnReloadModuleSave(). + * @param mod Reloaded module + * @param data Pointer that was passed to CustomData::add() in OnReloadModuleSave() at the time when the module's state + * was saved + */ + virtual void OnReloadModuleRestore(Module* mod, void* data) = 0; + }; +} -- cgit v1.2.3 From 19cc9292ab5889fa09962820f3179e8078bec956 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 26 Nov 2015 15:14:07 +0100 Subject: core_reloadmodule Allow modules to handle reload failures of other mods --- include/modules/reload.h | 2 +- src/coremods/core_reloadmodule.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'include/modules') diff --git a/include/modules/reload.h b/include/modules/reload.h index 6ee30c45e..dcdbc95e9 100644 --- a/include/modules/reload.h +++ b/include/modules/reload.h @@ -71,7 +71,7 @@ namespace ReloadModule virtual void OnReloadModuleSave(Module* mod, CustomData& cd) = 0; /** Restore data after a reload. Only called if data was added in OnReloadModuleSave(). - * @param mod Reloaded module + * @param mod Reloaded module, if NULL the reload failed and the module no longer exists * @param data Pointer that was passed to CustomData::add() in OnReloadModuleSave() at the time when the module's state * was saved */ diff --git a/src/coremods/core_reloadmodule.cpp b/src/coremods/core_reloadmodule.cpp index 755b49abf..0d01d9e85 100644 --- a/src/coremods/core_reloadmodule.cpp +++ b/src/coremods/core_reloadmodule.cpp @@ -236,6 +236,10 @@ class DataKeeper * @param newmod Newly loaded instance of the module which had its data saved */ void Restore(Module* newmod); + + /** Handle reload failure + */ + void Fail(); }; void DataKeeper::DoSaveUsers() @@ -468,6 +472,14 @@ void DataKeeper::Restore(Module* newmod) ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Restore finished"); } +void DataKeeper::Fail() +{ + this->mod = NULL; + + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Restore failed, notifying modules"); + DoRestoreModules(); +} + void DataKeeper::RestoreObj(const OwnedModesExts& data, Extensible* extensible, ModeType modetype, Modes::ChangeList& modechange) { RestoreExtensions(data.extlist, extensible); @@ -583,6 +595,8 @@ class ReloadAction : public HandlerBase0 Module* newmod = ServerInstance->Modules->Find(name); datakeeper.Restore(newmod); } + else + datakeeper.Fail(); ServerInstance->SNO->WriteGlobalSno('a', "RELOAD MODULE: %s %ssuccessfully reloaded", passedname.c_str(), result ? "" : "un"); User* user = ServerInstance->FindUUID(uuid); -- cgit v1.2.3