]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Maintain refcount of Module objects to complain about leaked pointers
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 19 Oct 2009 20:12:22 +0000 (20:12 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Mon, 19 Oct 2009 20:12:22 +0000 (20:12 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11925 e03df62e-2008-0410-955e-edbf42e46eb7

include/base.h
include/ctables.h
include/dns.h
include/extensible.h
include/mode.h
include/modules.h
src/base.cpp
src/modules.cpp

index 13efdd2dd943a18f883b0248a104de411e8011e9..0de37e781d6653796d589078e3dcf27a3f01d3bc 100644 (file)
@@ -179,21 +179,30 @@ class CoreExport CoreException : public std::exception
        }
 };
 
+class Module;
+
 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() {};
+       ModuleException(const std::string &message, Module* me = NULL);
+};
+
+class CoreExport ModuleRef : public reference_base
+{
+       Module* const value;
+ public:
+       ModuleRef(Module* v);
+       ~ModuleRef();
+       inline operator Module*() const { return value; }
+       inline Module* operator->() const { return value; }
+       inline Module& operator*() const { return *value; }
+ private:
+       ModuleRef(const ModuleRef&);
+       void operator=(const ModuleRef&);
+       void* operator new(size_t);
+       void operator delete(void*);
 };
 
 #endif
index cc80053d85de35e9c304fb5992cdabf631253368..80962b67ede477839c349ed1b6899bfbcf1fe5b2 100644 (file)
@@ -93,7 +93,7 @@ class CoreExport Command : public classbase
        const std::string command;
 
        /** Creator module - never NULL */
-       Module* const creator;
+       ModuleRef creator;
 
        /** User flags needed to execute the command or 0
         */
index 1b9ce59a4f7e4db5604afd0a2acaa6261c46ef59..eeaad4ef8c361e92098349df7352a56d2064384f 100644 (file)
@@ -187,7 +187,7 @@ class CoreExport Resolver
        /**
         * Pointer to creator module (if any, or NULL)
         */
-       Module* Creator;
+       ModuleRef Creator;
        /**
         * The input data, either a host or an IP address
         */
index e77c1cc305a1ed9f4303f24ab965ce242870f993..f0031e801f322424f8e31f0e45e1fdaea957e839 100644 (file)
@@ -19,7 +19,7 @@ class CoreExport ExtensionItem : public refcountbase
 {
  public:
        const std::string key;
-       Module* const owner;
+       ModuleRef owner;
        ExtensionItem(const std::string& key, Module* owner);
        virtual ~ExtensionItem();
        /** Serialize this item into a string
index b63e5e6a91116f3cc860a3db789745255f7621fe..76eeaba1705eaa3ffa86f77c568d2b93821f7d78 100644 (file)
@@ -157,7 +157,7 @@ class CoreExport ModeHandler : public classbase
 
  public:
        /** Module that created this mode. NULL for core modes */
-       Module* const creator;
+       ModuleRef creator;
        /** Long-form name
         */
        const std::string name;
@@ -370,7 +370,7 @@ class CoreExport ModeWatcher : public classbase
        ModeType m_type;
 
  public:
-       Module* const creator;
+       ModuleRef creator;
        /**
         * The constructor initializes the mode and the mode type
         */
index ad9cf05b8cee7021987d084f4323c85f978bc992..5e6cf13f5670a4b8b40017dd1de77695a7f244b5 100644 (file)
@@ -106,7 +106,7 @@ struct ModResult {
 /** If you change the module API in any way, increment this value.
  * This MUST be a pure integer, with no parenthesis
  */
-#define API_VERSION 135
+#define API_VERSION 136
 
 class ServerConfig;
 
@@ -266,10 +266,10 @@ class CoreExport Request : public classbase
        /** This is a pointer to the sender of the message, which can be used to
         * directly trigger events, or to create a reply.
         */
-       Module* const source;
+       ModuleRef source;
        /** The single destination of the Request
         */
-       Module* const dest;
+       ModuleRef dest;
 
        /** Create a new Request
         * This is for the 'new' way of defining a subclass
@@ -296,7 +296,7 @@ class CoreExport Event : public classbase
        /** This is a pointer to the sender of the message, which can be used to
         * directly trigger events, or to create a reply.
         */
-       Module* const source;
+       ModuleRef source;
        /** The event identifier.
         * This is arbitary text which should be used to distinguish
         * one type of event from another.
@@ -350,6 +350,8 @@ class ConfigReader;
  */
 class CoreExport Module : public classbase
 {
+       unsigned int refcount;
+       friend class reference_base;
  public:
        /** File that this module was loaded from
         */
index 389f3915a06fb96bfb8becc30f107d4664030c2b..c0bc40811a6ee0fd32a505471ee8e8f6cefe97a3 100644 (file)
@@ -270,3 +270,18 @@ void StringExtItem::free(void* item)
 {
        delete static_cast<std::string*>(item);
 }
+
+ModuleException::ModuleException(const std::string &message, Module* who)
+       : CoreException(message, who ? who->ModuleSourceFile : "A Module")
+{
+}
+
+ModuleRef::ModuleRef(Module* v) : value(v)
+{
+       if (value) inc(value);
+}
+
+ModuleRef::~ModuleRef()
+{
+       if (value) dec(value);
+}
index 87d25ac428d7ef7b8df3ae82bd5fc415653e1345..856addbf53371568256a0d826bde8694875a5555 100644 (file)
@@ -51,12 +51,16 @@ void Event::Send()
 
 // These declarations define the behavours of the base class Module (which does nothing at all)
 
-Module::Module() { }
+Module::Module() : refcount(0) { }
 CullResult Module::cull()
 {
        return classbase::cull();
 }
-Module::~Module() { }
+Module::~Module()
+{
+       if (refcount)
+               ServerInstance->Logs->Log("MODULE", DEFAULT, "References remain to destructed module " + ModuleSourceFile);
+}
 
 ModResult      Module::OnSendSnotice(char &snomask, std::string &type, const std::string &message) { return MOD_RES_PASSTHRU; }
 void           Module::OnUserConnect(User*) { }