summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-19 20:12:22 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-19 20:12:22 +0000
commitbe10eab6ce68d4f06cc7b14bc2fca35e005ce6b5 (patch)
treec22583006f80a8cb86bb15489c196832476cd28a
parentaa7cc18468f4b16bf79cd1788cad0cbf0d926817 (diff)
Maintain refcount of Module objects to complain about leaked pointers
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11925 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/base.h29
-rw-r--r--include/ctables.h2
-rw-r--r--include/dns.h2
-rw-r--r--include/extensible.h2
-rw-r--r--include/mode.h4
-rw-r--r--include/modules.h10
-rw-r--r--src/base.cpp15
-rw-r--r--src/modules.cpp8
8 files changed, 51 insertions, 21 deletions
diff --git a/include/base.h b/include/base.h
index 13efdd2dd..0de37e781 100644
--- a/include/base.h
+++ b/include/base.h
@@ -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
diff --git a/include/ctables.h b/include/ctables.h
index cc80053d8..80962b67e 100644
--- a/include/ctables.h
+++ b/include/ctables.h
@@ -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
*/
diff --git a/include/dns.h b/include/dns.h
index 1b9ce59a4..eeaad4ef8 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -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
*/
diff --git a/include/extensible.h b/include/extensible.h
index e77c1cc30..f0031e801 100644
--- a/include/extensible.h
+++ b/include/extensible.h
@@ -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
diff --git a/include/mode.h b/include/mode.h
index b63e5e6a9..76eeaba17 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -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
*/
diff --git a/include/modules.h b/include/modules.h
index ad9cf05b8..5e6cf13f5 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -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
*/
diff --git a/src/base.cpp b/src/base.cpp
index 389f3915a..c0bc40811 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -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);
+}
diff --git a/src/modules.cpp b/src/modules.cpp
index 87d25ac42..856addbf5 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -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*) { }