diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-12-01 12:23:50 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-12-01 12:23:50 +0100 |
commit | 44b5a8fa89d8c2bda767c0d5fe77c4d31061ce2b (patch) | |
tree | 0f1b3d375efd8584858e7df906de6bc322f4b5c6 /include | |
parent | 0a12e928e61cdb5366f0ad8ffb9d912eb14c5878 (diff) | |
parent | 19cc9292ab5889fa09962820f3179e8078bec956 (diff) |
Merge branch 'master+reloadmod'
Diffstat (limited to 'include')
-rw-r--r-- | include/extensible.h | 13 | ||||
-rw-r--r-- | include/modules.h | 16 | ||||
-rw-r--r-- | include/modules/reload.h | 80 |
3 files changed, 99 insertions, 10 deletions
diff --git a/include/extensible.h b/include/extensible.h index a2c104377..5ac4fa9da 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -121,11 +121,20 @@ class CoreExport Extensible : public classbase class CoreExport ExtensionManager { - std::map<std::string, reference<ExtensionItem> > types; public: + typedef std::map<std::string, reference<ExtensionItem> > ExtMap; + bool Register(ExtensionItem* item); void BeginUnregister(Module* module, std::vector<reference<ExtensionItem> >& list); ExtensionItem* GetItem(const std::string& name); + + /** Get all registered extensions keyed by their names + * @return Const map of ExtensionItem pointers keyed by their names + */ + const ExtMap& GetExts() const { return types; } + + private: + ExtMap types; }; /** Base class for items that are NOT synchronized between servers */ @@ -192,6 +201,7 @@ class CoreExport LocalStringExt : public SimpleExtItem<std::string> LocalStringExt(const std::string& key, ExtensibleType exttype, Module* owner); virtual ~LocalStringExt(); std::string serialize(SerializeFormat format, const Extensible* container, void* item) const; + void unserialize(SerializeFormat format, Extensible* container, const std::string& value); }; class CoreExport LocalIntExt : public LocalExtItem @@ -200,6 +210,7 @@ class CoreExport LocalIntExt : public LocalExtItem LocalIntExt(const std::string& key, ExtensibleType exttype, Module* owner); virtual ~LocalIntExt(); std::string serialize(SerializeFormat format, const Extensible* container, void* item) const; + void unserialize(SerializeFormat format, Extensible* container, const std::string& value); intptr_t get(const Extensible* container) const; intptr_t set(Extensible* container, intptr_t value); void unset(Extensible* container) { set(container, 0); } diff --git a/include/modules.h b/include/modules.h index c938e6a9d..f86f88087 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1035,9 +1035,6 @@ class CoreExport ModuleManager : public fakederef<ModuleManager> PRIO_STATE_LAST } prioritizationState; - /** Internal unload module hook */ - bool CanUnload(Module*); - /** Loads all core modules (cmd_*) */ void LoadCoreModules(std::map<std::string, ServiceList>& servicemap); @@ -1165,18 +1162,19 @@ class CoreExport ModuleManager : public fakederef<ModuleManager> */ bool Unload(Module* module); - /** Run an asynchronous reload of the given module. When the reload is - * complete, the callback will be run with true if the reload succeeded - * and false if it did not. - */ - void Reload(Module* module, HandlerBase1<void, bool>* callback); - /** Called by the InspIRCd constructor to load all modules from the config file. */ void LoadAll(); void UnloadAll(); void DoSafeUnload(Module*); + /** Check if a module can be unloaded and if yes, prepare it for unload + * @param mod Module to be unloaded + * @return True if the module is unloadable, false otherwise. + * If true the module must be unloaded in the current main loop iteration. + */ + bool CanUnload(Module* mod); + /** Find a module by name, and return a Module* to it. * This is preferred over iterating the module lists yourself. * @param name The module name to look up diff --git a/include/modules/reload.h b/include/modules/reload.h new file mode 100644 index 000000000..dcdbc95e9 --- /dev/null +++ b/include/modules/reload.h @@ -0,0 +1,80 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2015 Attila Molnar <attilamolnar@hush.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#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<Data> 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, 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 + */ + virtual void OnReloadModuleRestore(Module* mod, void* data) = 0; + }; +} |