diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/base.h | 62 | ||||
-rw-r--r-- | include/dynamic.h | 122 | ||||
-rw-r--r-- | include/globals.h | 1 | ||||
-rw-r--r-- | include/modules.h | 104 |
4 files changed, 145 insertions, 144 deletions
diff --git a/include/base.h b/include/base.h index e769e93b1..faea391a3 100644 --- a/include/base.h +++ b/include/base.h @@ -223,6 +223,66 @@ class CoreExport BoolSet : public classbase bool operator=(BoolSet other); }; +/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. + * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or + * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not + * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user + * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time. + */ +class CoreExport CoreException : public std::exception +{ + protected: + /** Holds the error message to be displayed + */ + const std::string err; + /** Source of the exception + */ + const std::string source; + public: + /** Default constructor, just uses the error mesage 'Core threw an exception'. + */ + CoreException() : err("Core threw an exception"), source("The core") {} + /** This constructor can be used to specify an error message before throwing. + */ + CoreException(const std::string &message) : err(message), source("The core") {} + /** This constructor can be used to specify an error message before throwing, + * and to specify the source of the exception. + */ + CoreException(const std::string &message, const std::string &src) : err(message), source(src) {} + /** This destructor solves world hunger, cancels the world debt, and causes the world to end. + * Actually no, it does nothing. Never mind. + * @throws Nothing! + */ + virtual ~CoreException() throw() {}; + /** Returns the reason for the exception. + * The module should probably put something informative here as the user will see this upon failure. + */ + virtual const char* GetReason() + { + return err.c_str(); + } -#endif + virtual const char* GetSource() + { + return source.c_str(); + } +}; + +class CoreExport ModuleException : public CoreException +{ + public: + /** Default constructor, just uses the error mesage 'Module threw an exception'. + */ + ModuleException() : CoreException("Module threw an exception", "A Module") {} + + /** This constructor can be used to specify an error message before throwing. + */ + ModuleException(const std::string &message) : CoreException(message, "A Module") {} + /** This destructor solves world hunger, cancels the world debt, and causes the world to end. + * Actually no, it does nothing. Never mind. + * @throws Nothing! + */ + virtual ~ModuleException() throw() {}; +}; +#endif diff --git a/include/dynamic.h b/include/dynamic.h index db46291c4..6de566117 100644 --- a/include/dynamic.h +++ b/include/dynamic.h @@ -14,21 +14,19 @@ #ifndef __DLL_H #define __DLL_H -/** This typedef represents the init_module function within each module. - * The init_module function is the only exported extern "C" declaration - * in any module file. - */ -typedef void * (initfunc) (void); - #include "inspircd_config.h" -class InspIRCd; - /** The DLLManager class is able to load a module file by filename, * and locate its init_module symbol. */ class CoreExport DLLManager { + protected: + + /** The last error string, or NULL + */ + char *err; + public: /** This constructor loads the module using dlopen() * @param ServerInstance The creator class of this object @@ -58,43 +56,64 @@ class CoreExport DLLManager * pointer (yes, really!) and on windows it is a library handle. */ void *h; - - protected: - - /** The last error string, or NULL - */ - char *err; }; -/** This class is a specialized form of DLLManager designed to load InspIRCd modules. - * It's job is to call the init_module function and receive a factory pointer. - */ -class CoreExport DLLFactoryBase : public DLLManager +class CoreExport LoadModuleException : public CoreException { public: - /** Default constructor. - * This constructor loads a module file by calling its DLLManager subclass constructor, - * then finds the symbol using DLLManager::GetSymbol(), and calls the symbol, - * obtaining a valid pointer to the init_module function + /** This constructor can be used to specify an error message before throwing. */ - DLLFactoryBase(InspIRCd* Instance, const char *fname, const char *func_name = 0); - - /** Default destructor. + LoadModuleException(const std::string &message) + : CoreException(message, "the core") + { + } + + /** This destructor solves world hunger, cancels the world debt, and causes the world to end. + * Actually no, it does nothing. Never mind. + * @throws Nothing! */ - virtual ~DLLFactoryBase(); + virtual ~LoadModuleException() throw() {}; +}; - /** A function pointer to the factory function. +class CoreExport FindSymbolException : public CoreException +{ + public: + /** This constructor can be used to specify an error message before throwing. + */ + FindSymbolException(const std::string &message) + : CoreException(message, "the core") + { + } + + /** This destructor solves world hunger, cancels the world debt, and causes the world to end. + * Actually no, it does nothing. Never mind. + * @throws Nothing! */ - void * (*factory_func)(void); + virtual ~FindSymbolException() throw() {}; }; -/** This is the highest-level class of the DLLFactory system used to load InspIRCd modules. - * Its job is to finally call the init_module function and obtain a pointer to a ModuleFactory. - * This template is a container for ModuleFactory itself, so that it may 'plug' into ModuleFactory - * and provide module loading capabilities transparently. +/** This is the highest-level class of the DLLFactory system used to load InspIRCd modules and commands. + * All the dirty mucking around with dl*() is done by DLLManager, all this does it put a pretty shell on + * it and make it nice to use to load modules and core commands. This class is quite specialised for these + * two uses and it may not be useful more generally -- use DLLManager directly for that. */ -template <class T> class CoreExport DLLFactory : public DLLFactoryBase +template <typename ReturnType> class CoreExport DLLFactory : public DLLManager { + protected: + /** This typedef represents the init_* function within each module or command. + * The init_module function is the only exported extern "C" declaration + * in any module file. In a cmd_*.cpp file the equivilant is init_command + */ + typedef ReturnType * (initfunctype) (InspIRCd*); + + /** Pointer to the init function. + */ + initfunctype* init_func; + + /** Instance pointer to be passed to init_*() when it is called. + */ + InspIRCd* ServerInstance; + public: /** Default constructor. * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager @@ -102,26 +121,41 @@ template <class T> class CoreExport DLLFactory : public DLLFactoryBase * class. It is then down to the core to call the ModuleFactory::CreateModule() method and * receive a Module* which it can insert into its module lists. */ - DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name=0) : DLLFactoryBase(Instance, fname, func_name) + DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name) + : DLLManager(Instance, fname), init_func(NULL), ServerInstance(Instance) + { + const char* error = LastError(); + + if(!error) + { + if(!GetSymbol((void **)&init_func, func_name)) + { + throw FindSymbolException("Missing " + std::string(func_name) + "() entrypoint!"); + } + } + else + { + throw LoadModuleException(error); + } + } + + ReturnType* CallInit() { - if (factory_func) - factory = reinterpret_cast<T*>(factory_func()); + if(init_func) + { + return init_func(ServerInstance); + } else - factory = reinterpret_cast<T*>(-1); + { + return NULL; + } } /** The destructor deletes the ModuleFactory pointer. */ ~DLLFactory() { - if (factory) - delete factory; } - - /** The ModuleFactory pointer. - */ - T *factory; }; #endif - diff --git a/include/globals.h b/include/globals.h index 4a01e454e..bf832be59 100644 --- a/include/globals.h +++ b/include/globals.h @@ -36,4 +36,3 @@ typedef std::vector< KeyVal > KeyValList; typedef std::multimap< std::string, KeyValList > ConfigDataHash; #endif - diff --git a/include/modules.h b/include/modules.h index df857d506..e5596430f 100644 --- a/include/modules.h +++ b/include/modules.h @@ -93,6 +93,7 @@ class ServerConfig; /* Forward-delacare module for ModuleMessage etc */ class Module; +class InspIRCd; /** Low level definition of a FileReader classes file cache area - * a text file seperated into lines. @@ -361,68 +362,6 @@ class CoreExport Event : public ModuleMessage char* Send(InspIRCd* ServerInstance); }; -/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. - * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or - * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not - * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user - * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time. - */ -class CoreExport CoreException : public std::exception -{ - protected: - /** Holds the error message to be displayed - */ - const std::string err; - /** Source of the exception - */ - const std::string source; - public: - /** Default constructor, just uses the error mesage 'Core threw an exception'. - */ - CoreException() : err("Core threw an exception"), source("The core") {} - /** This constructor can be used to specify an error message before throwing. - */ - CoreException(const std::string &message) : err(message), source("The core") {} - /** This constructor can be used to specify an error message before throwing, - * and to specify the source of the exception. - */ - CoreException(const std::string &message, const std::string &src) : err(message), source(src) {} - /** This destructor solves world hunger, cancels the world debt, and causes the world to end. - * Actually no, it does nothing. Never mind. - * @throws Nothing! - */ - virtual ~CoreException() throw() {}; - /** Returns the reason for the exception. - * The module should probably put something informative here as the user will see this upon failure. - */ - virtual const char* GetReason() - { - return err.c_str(); - } - - virtual const char* GetSource() - { - return source.c_str(); - } -}; - -class CoreExport ModuleException : public CoreException -{ - public: - /** Default constructor, just uses the error mesage 'Module threw an exception'. - */ - ModuleException() : CoreException("Module threw an exception", "A Module") {} - - /** This constructor can be used to specify an error message before throwing. - */ - ModuleException(const std::string &message) : CoreException(message, "A Module") {} - /** This destructor solves world hunger, cancels the world debt, and causes the world to end. - * Actually no, it does nothing. Never mind. - * @throws Nothing! - */ - virtual ~ModuleException() throw() {}; -}; - /** Priority types which can be returned from Module::Prioritize() */ enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }; @@ -1639,32 +1578,10 @@ class CoreExport FileReader : public classbase int FileSize(); }; - -/** Instantiates classes inherited from Module. - * This class creates a class inherited from type Module, using new. This is to allow for modules - * to create many different variants of Module, dependent on architecture, configuration, etc. - * In most cases, the simple class shown in the example module m_foobar.so will suffice for most - * modules. - */ -class CoreExport ModuleFactory : public classbase -{ - public: - /** The default constructor does nothing. - */ - ModuleFactory() { } - /** The default destructor does nothing - */ - virtual ~ModuleFactory() { } - /** Creates a new module. - * Your inherited class of ModuleFactory must return a pointer to your Module class - * using this method. - */ - virtual Module * CreateModule(InspIRCd* Me) = 0; -}; - -/** A DLLFactory (designed to load shared objects) containing a ModuleFactory. +/** A DLLFactory (designed to load shared objects) containing a + * handle to a module's init_module() function. */ -typedef DLLFactory<ModuleFactory> ircd_module; +typedef DLLFactory<Module> ircd_module; /** A list of loaded Modules */ @@ -1679,18 +1596,9 @@ typedef std::vector<ircd_module*> FactoryList; * It defines the class factory and external init_module function. */ #define MODULE_INIT(y) \ - class Factory : public ModuleFactory \ + extern "C" DllExport Module * init_module(InspIRCd* Me) \ { \ - public: \ - virtual Module * CreateModule(InspIRCd* Me) \ - { \ - return new y(Me); \ - } \ - }; \ - extern "C" DllExport void * init_module(void) \ - { \ - return new Factory; \ + return new y(Me); \ } #endif - |