You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvilib/ext/kvi_garbage.cpp

149 lines
4.0 KiB

//
// 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 <tqvariant.h>
KviGarbageCollector::KviGarbageCollector()
: TQObject(0)
{
m_pGarbageList = 0;
m_pCleanupTimer = 0;
m_bForceCleanupNow = false;
}
KviGarbageCollector::~KviGarbageCollector()
{
m_bForceCleanupNow = true;
cleanup();
}
void KviGarbageCollector::collect(TQObject * g)
{
if(!m_pGarbageList)
{
m_pGarbageList = new KviPointerList<TQObject>;
m_pGarbageList->setAutoDelete(true);
}
//tqDebug("COLLECTING GARBAGE %s",g->className());
m_pGarbageList->append(g);
// tqDebug("Registering garbage object %d (%s:%s)",g,g->className(),g->name());
connect(g,TQT_SIGNAL(destroyed()),this,TQT_SLOT(garbageSuicide()));
triggerCleanup(0);
}
void KviGarbageCollector::garbageSuicide()
{
if(!m_pGarbageList)
{
tqDebug("Ops... garbage suicide while no garbage list");
return;
}
int idx = m_pGarbageList->findRef(TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender())));
if(idx == -1)
{
tqDebug("Ops... unregistered garbage suicide");
return;
}
m_pGarbageList->removeRef(TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender())));
if(m_pGarbageList->isEmpty())
{
cleanup();
}
}
void KviGarbageCollector::triggerCleanup(int iTimeout)
{
//tqDebug("TRIGGERING CLEANUP AFTER %d msecs",iTimeout);
if(m_pCleanupTimer)
{
m_pCleanupTimer->stop();
} else {
m_pCleanupTimer = new TQTimer(this);
connect(m_pCleanupTimer,TQT_SIGNAL(timeout()),this,TQT_SLOT(cleanup()));
}
m_pCleanupTimer->start(iTimeout);
}
void KviGarbageCollector::cleanup()
{
//tqDebug("CLEANUP CALLED !");
if(m_pGarbageList)
{
//tqDebug("SOME GARBAGE TO DELETE");
KviPointerList<TQObject> dying;
dying.setAutoDelete(false);
for(TQObject * o = m_pGarbageList->first();o;o = m_pGarbageList->next())
{
//tqDebug("CHECKING GARBAGE CLASS %s",o->className());
bool bDeleteIt = m_bForceCleanupNow;
if(!bDeleteIt)
{
//tqDebug("CLEANUP NOT FORCED");
TQVariant v = o->property("blockingDelete");
if(v.isValid())
{
//tqDebug("HAS A VALID VARIANT!");
// tqDebug("[Garbage collector]: garbage has a blockingDelete property");
bDeleteIt = !(v.toBool());
// if(!bDeleteIt)tqDebug("And doesn't want to be delete now!");
} else bDeleteIt = true; // must be deleted
}
if(bDeleteIt)dying.append(o);
}
for(TQObject * o2 = dying.first();o2;o2 = dying.next())
{
//tqDebug("KILLING GARBAGE CLASS %s",o2->className());
disconnect(o2,TQT_SIGNAL(destroyed()),this,TQT_SLOT(garbageSuicide()));
m_pGarbageList->removeRef(o2);
}
if(m_pGarbageList->isEmpty())
{
delete m_pGarbageList;
m_pGarbageList = 0;
}
}
if(m_pGarbageList)
{
// tqDebug("[Garbage collector cleanup]: Some stuff left to be deleted, will retry in a while");
// something left to be destroyed
if(m_bForceCleanupNow)tqDebug("[Garbage collector]: Ops...I've left some undeleted stuff!");
triggerCleanup(5000); // retry in 5 sec
} else {
// tqDebug("[Garbage collector cleanup]: Completed");
// nothing left to delete
if(m_pCleanupTimer)
{
delete m_pCleanupTimer;
m_pCleanupTimer = 0;
}
}
}