summaryrefslogtreecommitdiffstats
path: root/src/kvilib/ext/kvi_garbage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kvilib/ext/kvi_garbage.cpp')
-rw-r--r--src/kvilib/ext/kvi_garbage.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/kvilib/ext/kvi_garbage.cpp b/src/kvilib/ext/kvi_garbage.cpp
new file mode 100644
index 00000000..0e2e8881
--- /dev/null
+++ b/src/kvilib/ext/kvi_garbage.cpp
@@ -0,0 +1,148 @@
+//
+// File : kvi_garbage.cpp
+// Creation date : Mon Dec 3 16:49:15 2001 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVILIB__
+
+
+
+#include "kvi_garbage.h"
+
+#include <qvariant.h>
+
+KviGarbageCollector::KviGarbageCollector()
+: QObject(0)
+{
+ m_pGarbageList = 0;
+ m_pCleanupTimer = 0;
+ m_bForceCleanupNow = false;
+}
+
+KviGarbageCollector::~KviGarbageCollector()
+{
+ m_bForceCleanupNow = true;
+ cleanup();
+}
+
+void KviGarbageCollector::collect(QObject * g)
+{
+ if(!m_pGarbageList)
+ {
+ m_pGarbageList = new KviPointerList<QObject>;
+ m_pGarbageList->setAutoDelete(true);
+ }
+ //debug("COLLECTING GARBAGE %s",g->className());
+ m_pGarbageList->append(g);
+// debug("Registering garbage object %d (%s:%s)",g,g->className(),g->name());
+ connect(g,SIGNAL(destroyed()),this,SLOT(garbageSuicide()));
+ triggerCleanup(0);
+}
+
+void KviGarbageCollector::garbageSuicide()
+{
+ if(!m_pGarbageList)
+ {
+ debug("Ops... garbage suicide while no garbage list");
+ return;
+ }
+ int idx = m_pGarbageList->findRef(sender());
+ if(idx == -1)
+ {
+ debug("Ops... unregistered garbage suicide");
+ return;
+ }
+ m_pGarbageList->removeRef(sender());
+ if(m_pGarbageList->isEmpty())
+ {
+ cleanup();
+ }
+}
+
+void KviGarbageCollector::triggerCleanup(int iTimeout)
+{
+ //debug("TRIGGERING CLEANUP AFTER %d msecs",iTimeout);
+ if(m_pCleanupTimer)
+ {
+ m_pCleanupTimer->stop();
+ } else {
+ m_pCleanupTimer = new QTimer(this);
+ connect(m_pCleanupTimer,SIGNAL(timeout()),this,SLOT(cleanup()));
+ }
+ m_pCleanupTimer->start(iTimeout);
+}
+
+void KviGarbageCollector::cleanup()
+{
+ //debug("CLEANUP CALLED !");
+ if(m_pGarbageList)
+ {
+ //debug("SOME GARBAGE TO DELETE");
+ KviPointerList<QObject> dying;
+ dying.setAutoDelete(false);
+ for(QObject * o = m_pGarbageList->first();o;o = m_pGarbageList->next())
+ {
+ //debug("CHECKING GARBAGE CLASS %s",o->className());
+ bool bDeleteIt = m_bForceCleanupNow;
+ if(!bDeleteIt)
+ {
+ //debug("CLEANUP NOT FORCED");
+ QVariant v = o->property("blockingDelete");
+ if(v.isValid())
+ {
+ //debug("HAS A VALID VARIANT!");
+// debug("[Garbage collector]: garbage has a blockingDelete property");
+ bDeleteIt = !(v.toBool());
+// if(!bDeleteIt)debug("And doesn't want to be delete now!");
+ } else bDeleteIt = true; // must be deleted
+ }
+ if(bDeleteIt)dying.append(o);
+ }
+
+ for(QObject * o2 = dying.first();o2;o2 = dying.next())
+ {
+ //debug("KILLING GARBAGE CLASS %s",o2->className());
+ disconnect(o2,SIGNAL(destroyed()),this,SLOT(garbageSuicide()));
+ m_pGarbageList->removeRef(o2);
+ }
+
+ if(m_pGarbageList->isEmpty())
+ {
+ delete m_pGarbageList;
+ m_pGarbageList = 0;
+ }
+ }
+
+ if(m_pGarbageList)
+ {
+// debug("[Garbage collector cleanup]: Some stuff left to be deleted, will retry in a while");
+ // something left to be destroyed
+ if(m_bForceCleanupNow)debug("[Garbage collector]: Ops...I've left some undeleted stuff!");
+ triggerCleanup(5000); // retry in 5 sec
+ } else {
+// debug("[Garbage collector cleanup]: Completed");
+ // nothing left to delete
+ if(m_pCleanupTimer)
+ {
+ delete m_pCleanupTimer;
+ m_pCleanupTimer = 0;
+ }
+ }
+}
+