]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Force heap allocation of refcountbase, create usecountbase for non-allocation referen...
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 25 Oct 2009 20:03:55 +0000 (20:03 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 25 Oct 2009 20:03:55 +0000 (20:03 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11978 e03df62e-2008-0410-955e-edbf42e46eb7

include/base.h
include/extensible.h
include/inspsocket.h
include/modules.h
src/base.cpp
src/inspircd.cpp
src/modules.cpp
src/modules/m_showwhois.cpp

index b39c7d0778463e0f8bb478073c27859f002818f6..bc096b85bdd9e54ee629df5e94c245638f048d5e 100644 (file)
@@ -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
index 81859b1c89a3afc0e29b538c9f8a6f1e235f606b..487b67408e7b5b741db37e5a7afca3cd6141f8e1 100644 (file)
@@ -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;
index 3e5c752356458122b11b2ca6e70958cfa8931857..8172338ac2d5f0b8647d0f08ca5da70dbb664ac5 100644 (file)
@@ -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; }
index 8bda9a725efc10789e6d4fa8eac5c82c8bac2deb..26c4ef46658ef4407347498b8efd20dd0f23654e 100644 (file)
@@ -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
         */
index bf42327544dd925b6b951ed03fe226ec2d998478..8e81f7b73d09b83a16ef730339edf989c94850d6 100644 (file)
@@ -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);
-}
index 58480668b99e1d01db636dd40c1fcfd077ad8550..b67815ed24a6c09c360121bb71a7b00cec4059e1 100644 (file)
@@ -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.
index a1c53a1e8b8829dc850bde8c6d828329d917d50c..b3aabf284c10f6fb6f111987df5f1bade731378a 100644 (file)
@@ -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; }
index be1871badb043b62674f99b8039f3bc1dd6db607..074f1941c6d5d4de538b77cbba5d6e7b33877bb2 100644 (file)
@@ -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))