Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

GC.C

00001 /* $Id: GC.C,v 1.2 2000/11/03 22:03:28 rpav Exp $
00002  *
00003  * SFW - Studio FrameWork
00004  * Copyright (C) 2000  Ryan Pavlik
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  *
00020  */
00021 
00022 /*
00023  * Mini pseudo-garbage collector
00024  *
00025  */ 
00026 
00027 #include <unistd.h>
00028 #include <SFW/Log.H>
00029 #include <SFW/GC.H>
00030 
00031 TYPE_INIT(SFW::_GC);
00032 
00033 using namespace SFW;
00034 
00035 _GC SFW::GC;
00036 
00037 _GC::_GC() : m(QUICK) { }
00038 
00039 void _GC::finalize() {
00040     /* When we go away, let's clean up any last things, and
00041      * make note of anything with a non-zero refcount.
00042      */
00043     Log(L_DBG5, "GC: finalizing");
00044 
00045     /* Clear up all the stuff that's properly dereferenced */
00046     collect();
00047 
00048     m.lock();
00049     RefMap::iterator i = refmap.begin();
00050     
00051     if(i != refmap.end())
00052         Log(L_DBG0, "GC: final cleanup loop");
00053 
00054     while(i != refmap.end()) {
00055         m.unlock();
00056         int ref = i->second;
00057     if(ref != 0) {
00058             Log(L_DBG0, "GC Warning: Object (%s) with refcount [%d] at GC "
00059         "finalization (deleting)", i->first->getType().c_str(),
00060                 ref);
00061     }
00062 
00063     Log(L_DBG5, "GC: deleting %p (%s)", i->first,
00064             i->first->getType().c_str());
00065 
00066     delete i->first;
00067         m.lock();
00068     i++;
00069     }
00070 
00071     m.unlock();
00072 }
00073 
00074 void _GC::use(Object *_o) {
00075     m.lock();
00076     RefMap::iterator p;
00077     
00078     if((p = refmap.find(_o)) != refmap.end()) {
00079     /* Increment the refcount */
00080         int ref = ++refmap[_o];
00081         
00082     Log(L_DBG5, "GC: incref %p (%s) [%d]", _o, _o->getType().c_str(), ref);
00083     } else {
00084     /* Add it to our pool */
00085     Log(L_DBG5, "GC: addref %p (%s)", _o, _o->getType().c_str());
00086 
00087     refmap[_o] = 1;
00088     }
00089     m.unlock();
00090 }
00091 
00092 void _GC::done(Object *_o) {
00093     m.lock();
00094     
00095     RefMap::iterator p;
00096 
00097     if((p = refmap.find(_o)) != refmap.end()) {
00098         /* Decrement the refcount */
00099         int ref = --refmap[_o];
00100 
00101     Log(L_DBG5, "GC: decref %p (%s) [%d]", _o,
00102             _o->getType().c_str(), ref);
00103 
00104     if(refmap[_o] < 0)
00105         Log(L_DBG0, "GC Warning: Object (%s) has acquired negative refcount!",
00106                 _o->getType().c_str());
00107     } else {
00108     Log(L_DBG0, "GC Warning: Attempt to decref something I don't know about!"
00109             " [%p]", _o);
00110     }
00111 
00112     m.unlock();
00113 }
00114 
00115 void _GC::collect() {
00116     RefMap::iterator i, i_tmp;
00117     bool deletedSome = true;
00118 
00119     m.lock();
00120     i = refmap.begin();
00121     m.unlock();
00122     
00123     while(deletedSome) {
00124         deletedSome = false;
00125 
00126         while(m.lock(), i != refmap.end()) {
00127             m.unlock();
00128             
00129             int ref = i->second;
00130             
00131             if(ref == 0) {
00132                 Log(L_DBG5, "GC: deleting %p (%s) [%d]", i->first,
00133                     i->first->getType().c_str(), ref);
00134         
00135                 i_tmp = i;
00136                 m.lock();
00137                 i++;
00138                 m.unlock();
00139 
00140                 delete i_tmp->first;
00141                 m.lock();
00142                 refmap.erase(i_tmp);
00143                 m.unlock();
00144 
00145                 deletedSome = true;
00146             } else {
00147                 m.lock();
00148                 i++;
00149                 m.unlock();
00150             }
00151         }
00152 
00153         /* Will be locked because of while() */
00154         i = refmap.begin();
00155         m.unlock();
00156     }
00157 }
00158 
00159 void _GC::main() {
00160     /* CHECK: This isn't very sophisticated yet */
00161     while(1) {
00162         testCancel();
00163         sleep(5);
00164         testCancel();
00165         collect();
00166     }
00167 }

Generated at Tue Jan 2 15:38:33 2001 for SFW by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000