virtual ~refcountbase();
inline unsigned int GetReferenceCount() const { return refcount; }
friend class reference_base;
+ void* operator new(size_t);
+ void operator delete(void*);
private:
// uncopyable
refcountbase(const refcountbase&);
protected:
template<typename T> static inline unsigned int inc(T* v) { return ++(v->refcount); }
template<typename T> static inline unsigned int dec(T* v) { return --(v->refcount); }
+
};
template <typename T>
ModuleException(const std::string &message, Module* me = NULL);
};
+/** Module reference, similar to reference<Module>
+ */
class CoreExport ModuleRef : public reference_base
{
Module* const value;
{
}
-refcountbase::refcountbase() : refcount(0)
+// This trick detects heap allocations of refcountbase objects
+static void* last_heap = NULL;
+static const unsigned int top_bit = 1 << (8*sizeof(unsigned int) - 1);
+
+void* refcountbase::operator new(size_t size)
+{
+ last_heap = ::operator new(size);
+ return last_heap;
+}
+
+void refcountbase::operator delete(void* obj)
{
+ if (last_heap == obj)
+ last_heap = NULL;
+ ::operator delete(obj);
+}
+
+refcountbase::refcountbase()
+{
+ if (this == last_heap)
+ refcount = 0;
+ else
+ refcount = top_bit;
}
refcountbase::~refcountbase()
{
- if (refcount && ServerInstance && ServerInstance->Logs)
- ServerInstance->Logs->Log("CULLLIST", DEBUG, "refcountbase::~ @%p with refcount %d",
+ if ((refcount & ~top_bit) && ServerInstance && ServerInstance->Logs)
+ ServerInstance->Logs->Log("CULLLIST", DEBUG, "refcountbase::~ @%p with refcount %x",
(void*)this, refcount);
}
// These declarations define the behavours of the base class Module (which does nothing at all)
-Module::Module() : refcount(0) { }
+Module::Module() : refcount(1) { }
CullResult Module::cull()
{
return classbase::cull();
}
Module::~Module()
{
- if (refcount)
+ if (refcount != 1)
ServerInstance->Logs->Log("MODULE", DEFAULT, "References remain to destructed module " + ModuleSourceFile);
}