mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Force heap allocation of refcountbase, create usecountbase for non-allocation reference counting
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11978 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
parent
5c05313b6e
commit
fa2cdd0bb8
@ -81,35 +81,46 @@ class CoreExport refcountbase
|
||||
refcountbase();
|
||||
virtual ~refcountbase();
|
||||
inline unsigned int GetReferenceCount() const { return refcount; }
|
||||
friend class reference_base;
|
||||
void* operator new(size_t);
|
||||
void operator delete(void*);
|
||||
inline void refcount_inc() const { refcount++; }
|
||||
inline bool refcount_dec() const { refcount--; return !refcount; }
|
||||
private:
|
||||
// uncopyable
|
||||
refcountbase(const refcountbase&);
|
||||
void operator=(const refcountbase&);
|
||||
};
|
||||
|
||||
class CoreExport reference_base
|
||||
/** Base class for use count tracking. Uses reference<>, but does not
|
||||
* cause object deletion when the last user is removed.
|
||||
*/
|
||||
class CoreExport usecountbase
|
||||
{
|
||||
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); }
|
||||
|
||||
mutable unsigned int usecount;
|
||||
public:
|
||||
usecountbase() : usecount(0) { }
|
||||
~usecountbase();
|
||||
inline unsigned int GetUseCount() const { return usecount; }
|
||||
inline void refcount_inc() const { usecount++; }
|
||||
inline bool refcount_dec() const { usecount--; return false; }
|
||||
private:
|
||||
// uncopyable
|
||||
usecountbase(const usecountbase&);
|
||||
void operator=(const usecountbase&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class reference : public reference_base
|
||||
class reference
|
||||
{
|
||||
T* value;
|
||||
public:
|
||||
reference() : value(0) { }
|
||||
reference(T* v) : value(v) { if (value) inc(value); }
|
||||
reference(const reference<T>& v) : value(v.value) { if (value) inc(value); }
|
||||
reference(T* v) : value(v) { if (value) value->refcount_inc(); }
|
||||
reference(const reference<T>& v) : value(v.value) { if (value) value->refcount_inc(); }
|
||||
reference<T>& operator=(const reference<T>& other)
|
||||
{
|
||||
if (other.value)
|
||||
inc(other.value);
|
||||
other.value->refcount_inc();
|
||||
this->reference::~reference();
|
||||
value = other.value;
|
||||
return *this;
|
||||
@ -117,12 +128,8 @@ class reference : public reference_base
|
||||
|
||||
~reference()
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
int rc = dec(value);
|
||||
if (rc == 0)
|
||||
delete value;
|
||||
}
|
||||
if (value && value->refcount_dec())
|
||||
delete value;
|
||||
}
|
||||
inline operator bool() const { return value; }
|
||||
inline operator T*() const { return value; }
|
||||
@ -130,8 +137,6 @@ class reference : public reference_base
|
||||
inline T& operator*() const { return *value; }
|
||||
inline bool operator<(const reference<T>& other) const { return value < other.value; }
|
||||
inline bool operator>(const reference<T>& other) const { return value > other.value; }
|
||||
inline bool operator==(const reference<T>& other) const { return value == other.value; }
|
||||
inline bool operator!=(const reference<T>& other) const { return value != other.value; }
|
||||
private:
|
||||
void* operator new(size_t);
|
||||
void operator delete(void*);
|
||||
@ -190,22 +195,6 @@ class CoreExport ModuleException : public CoreException
|
||||
ModuleException(const std::string &message, Module* me = NULL);
|
||||
};
|
||||
|
||||
/** Module reference, similar to reference<Module>
|
||||
*/
|
||||
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*);
|
||||
};
|
||||
typedef const reference<Module> ModuleRef;
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@ enum SerializeFormat
|
||||
|
||||
/** Class represnting an extension of some object
|
||||
*/
|
||||
class CoreExport ExtensionItem : public refcountbase
|
||||
class CoreExport ExtensionItem : public usecountbase
|
||||
{
|
||||
public:
|
||||
const std::string key;
|
||||
|
@ -94,7 +94,7 @@ class CoreExport SocketTimeout : public Timer
|
||||
class CoreExport StreamSocket : public EventHandler
|
||||
{
|
||||
/** Module that handles raw I/O for this socket, or NULL */
|
||||
Module *IOHook;
|
||||
reference<Module> IOHook;
|
||||
/** Private send queue. Note that individual strings may be shared
|
||||
*/
|
||||
std::deque<std::string> sendq;
|
||||
@ -105,7 +105,7 @@ class CoreExport StreamSocket : public EventHandler
|
||||
protected:
|
||||
std::string recvq;
|
||||
public:
|
||||
StreamSocket() : IOHook(NULL), sendq_len(0) {}
|
||||
StreamSocket() : sendq_len(0) {}
|
||||
inline Module* GetIOHook() { return IOHook; }
|
||||
inline void AddIOHook(Module* m) { IOHook = m; }
|
||||
inline void DelIOHook() { IOHook = NULL; }
|
||||
|
@ -298,10 +298,8 @@ enum Implementation
|
||||
* its methods will be called when irc server events occur. class inherited from module must be
|
||||
* instantiated by the ModuleFactory class (see relevent section) for the module to be initialised.
|
||||
*/
|
||||
class CoreExport Module : public classbase
|
||||
class CoreExport Module : public classbase, public usecountbase
|
||||
{
|
||||
unsigned int refcount;
|
||||
friend class reference_base;
|
||||
public:
|
||||
/** File that this module was loaded from
|
||||
*/
|
||||
|
29
src/base.cpp
29
src/base.cpp
@ -43,7 +43,6 @@ CullResult::CullResult()
|
||||
|
||||
// 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)
|
||||
{
|
||||
@ -58,21 +57,26 @@ void refcountbase::operator delete(void* obj)
|
||||
::operator delete(obj);
|
||||
}
|
||||
|
||||
refcountbase::refcountbase()
|
||||
refcountbase::refcountbase() : refcount(0)
|
||||
{
|
||||
if (this == last_heap)
|
||||
refcount = 0;
|
||||
else
|
||||
refcount = top_bit;
|
||||
if (this != last_heap)
|
||||
throw CoreException("Reference allocate on the stack!");
|
||||
}
|
||||
|
||||
refcountbase::~refcountbase()
|
||||
{
|
||||
if ((refcount & ~top_bit) && ServerInstance && ServerInstance->Logs)
|
||||
ServerInstance->Logs->Log("CULLLIST", DEBUG, "refcountbase::~ @%p with refcount %x",
|
||||
if (refcount && ServerInstance && ServerInstance->Logs)
|
||||
ServerInstance->Logs->Log("CULLLIST", DEBUG, "refcountbase::~ @%p with refcount %d",
|
||||
(void*)this, refcount);
|
||||
}
|
||||
|
||||
usecountbase::~usecountbase()
|
||||
{
|
||||
if (usecount && ServerInstance && ServerInstance->Logs)
|
||||
ServerInstance->Logs->Log("CULLLIST", DEBUG, "usecountbase::~ @%p with refcount %d",
|
||||
(void*)this, usecount);
|
||||
}
|
||||
|
||||
ExtensionItem::ExtensionItem(const std::string& Key, Module* mod) : key(Key), owner(mod)
|
||||
{
|
||||
}
|
||||
@ -297,12 +301,3 @@ ModuleException::ModuleException(const std::string &message, Module* who)
|
||||
{
|
||||
}
|
||||
|
||||
ModuleRef::ModuleRef(Module* v) : value(v)
|
||||
{
|
||||
if (value) inc(value);
|
||||
}
|
||||
|
||||
ModuleRef::~ModuleRef()
|
||||
{
|
||||
if (value) dec(value);
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ void InspIRCd::Cleanup()
|
||||
/* Must be deleted before modes as it decrements modelines */
|
||||
if (FakeClient)
|
||||
FakeClient->cull();
|
||||
if (Res)
|
||||
Res->cull();
|
||||
DeleteZero(this->FakeClient);
|
||||
DeleteZero(this->Users);
|
||||
DeleteZero(this->Modes);
|
||||
@ -523,7 +525,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
|
||||
this->Config->Apply(NULL, "");
|
||||
Logs->OpenFileLogs();
|
||||
|
||||
this->Res = new DNS;
|
||||
this->Res = new DNS();
|
||||
|
||||
/*
|
||||
* Initialise SID/UID.
|
||||
|
@ -51,15 +51,13 @@ void Event::Send()
|
||||
|
||||
// These declarations define the behavours of the base class Module (which does nothing at all)
|
||||
|
||||
Module::Module() : refcount(1) { }
|
||||
Module::Module() { }
|
||||
CullResult Module::cull()
|
||||
{
|
||||
return classbase::cull();
|
||||
}
|
||||
Module::~Module()
|
||||
{
|
||||
if (refcount != 1)
|
||||
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; }
|
||||
|
@ -110,7 +110,7 @@ class ModuleShowwhois : public Module
|
||||
if (!dest->IsModeSet('W') || source == dest)
|
||||
return;
|
||||
|
||||
if (!ShowWhoisFromOpers && (IS_OPER(source) != IS_OPER(dest)))
|
||||
if (!ShowWhoisFromOpers && (!IS_OPER(source) != !IS_OPER(dest)))
|
||||
return;
|
||||
|
||||
if (IS_LOCAL(dest))
|
||||
|
Loading…
x
Reference in New Issue
Block a user