/home/vlg/develop/libASSA/libassa/assa/TimerQueue.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                            TimerQueue.cpp
00004 //------------------------------------------------------------------------------
00005 //  Copyright (c) 2000,2005 by Vladislav Grinchenko
00006 //
00007 //  This library is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU Library General Public
00009 //  License as published by the Free Software Foundation; either
00010 //  version 2 of the License, or (at your option) any later version.
00011 //
00012 //------------------------------------------------------------------------------
00013 //  Created: 07/28/99
00014 //------------------------------------------------------------------------------
00015 
00016 #include "assa/TimerQueue.h"
00017 using namespace ASSA;
00018 
00019 TimerQueue::
00020 ~TimerQueue () 
00021 { 
00022     trace_with_mask("TimerQueue::~TimerQueue",REACTTRACE);
00023 
00024     while (m_queue.size ()) {
00025         delete m_queue.pop ();
00026     }
00027 }
00028 
00029 int
00030 TimerQueue::
00031 remove (EventHandler* eh_)
00032 { 
00033     // Like STL iterators, after deletion of an element,
00034     // queue structure and indexing might drastically change
00035     // and there is no guarantee that elements we haven't seen
00036     // yet will not be moved past the iterator. Therefore,
00037     // we must start scanning from the beginning after each deletion :-(
00038 
00039     trace_with_mask("TimerQueue::remove(eh_)",REACTTRACE);
00040 
00041     register size_t i;
00042     int cnt = 0;
00043     bool f = true;      // changed flag
00044     register Timer* tmr;
00045 
00046     DL((REACT,"Searching for Timer: 0x%x\n", dynamic_cast<void*> (eh_)));
00047 
00048     while (f) {
00049         f = false;
00050         DL((REACT,"Queue size: %d\n", m_queue.size()));
00051         for (i = 0; i < m_queue.size (); i++) {
00052             if (m_queue[i]->getHandler() == eh_) {
00053                 DL((REACT,"Found Timer: 0x%x in slot: %d\n", 
00054                     dynamic_cast<void*>(eh_), i));
00055                 tmr = m_queue[i];
00056                 m_queue.remove (tmr);
00057                 delete tmr;
00058                 cnt++;
00059                 f = true;
00060             }
00061         }
00062     }
00063     return cnt;
00064 }
00065 
00066 bool
00067 TimerQueue::
00068 remove (TimerId tid_)
00069 { 
00070     trace_with_mask("TimerQueue::remove(tid)",REACTTRACE);
00071     register size_t i;
00072 
00073     DL((REACTTRACE,"Queue size before remove: %d\n", m_queue.size()));
00074 
00075     for (i = 0; i < m_queue.size (); i++) {
00076         if (m_queue[i] == (Timer*) tid_) {
00077             Timer* tmr = m_queue[i];
00078             int ret = m_queue.remove (tmr);
00079             delete tmr;
00080             DL((REACTTRACE,"Queue size after remove: %d\n", m_queue.size()));
00081             return ret;
00082         }
00083     }
00084     return false;
00085 }
00086 
00087 int
00088 TimerQueue::
00089 expire (const TimeVal& tv_)
00090 { 
00091     trace_with_mask("TimerQueue::expire",REACTTRACE);
00092 
00093     register Timer* tp = (Timer*) NULL;
00094     register int cnt = 0;
00095 
00096     while (m_queue.size () && (tp = m_queue.top ()) != (Timer*) NULL) {
00097         if (tp->getExpirationTime () > tv_) {
00098             DL((REACT,"Top timer:\n"));
00099             tp->dump ();
00100             break;
00101         }
00102         /* First, pop item from the queue. Then call an appropriate
00103            EventHandler. If done in reverse, EventHandler might
00104            remove item first and then pop () will fail
00105            (This needs more investigation!).
00106         */
00107         m_queue.pop ();
00108 
00109         DL((REACT,"Expired %s [t=%s] timer!\n",
00110             tp->get_id ().c_str (),
00111             tp->getExpirationTime ().fmtString ().c_str ()));
00112 
00113         int ret = tp->getHandler ()->handle_timeout ((TimerId) tp);
00114 
00118         if (ret == 1) {         
00119             tp->rescheduleExpirationTime ();
00120             m_queue.insert (tp);
00121         }
00122         else {
00123             delete tp;
00124             tp = (Timer*)NULL;
00125         }
00126         cnt++;
00127     }
00128 
00129     if (cnt) {
00130         DL((TRACE,"Expired total of %d timer(s).\n",cnt));
00131     }
00132 
00133     return cnt;
00134 }
00135 
00136 TimerId
00137 TimerQueue::
00138 insert (EventHandler*      eh_, 
00139         const TimeVal&     tv_, 
00140         const TimeVal&     delta_,
00141         const std::string& name_) 
00142 { 
00143     trace("TimerQueue::insert");
00144 
00145     Timer* t = new Timer (eh_, tv_, delta_, name_);
00146     m_queue.insert (t);
00147     return (TimerId) t;
00148 }
00149 
00150 void
00151 TimerQueue::
00152 dump (void)
00153 {
00154     trace("TimerQueue::dump");
00155 
00156     if (m_queue.size() == 0) {
00157         DL((REACT,"Queue is empty\n"));
00158     }
00159     else {
00160         for (size_t i = 0; i < m_queue.size (); ) {
00161             m_queue[i++]->dump();
00162         }
00163     }
00164 }

Generated on Sun Aug 13 15:08:00 2006 for libassa by  doxygen 1.4.6