LCOV - code coverage report
Current view: top level - src - Timer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 48 113 42.5 %
Date: 2010-12-13 Functions: 11 31 35.5 %
Branches: 21 96 21.9 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Timer.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "util.h"
       8                 :            : #include "Timer.h"
       9                 :            : #include "Desc.h"
      10                 :            : #include "Serializer.h"
      11                 :            : 
      12                 :            : // Names of timers in same order than in TimerType.
      13                 :            : const char* TimerNames[] = {
      14                 :            :         "BackdoorTimer",
      15                 :            :         "BreakpointTimer",
      16                 :            :         "ConnectionDeleteTimer",
      17                 :            :         "ConnectionExpireTimer",
      18                 :            :         "ConnectionInactivityTimer",
      19                 :            :         "ConnectionStatusUpdateTimer",
      20                 :            :         "DNSExpireTimer",
      21                 :            :         "FragTimer",
      22                 :            :         "IncrementalSendTimer",
      23                 :            :         "IncrementalWriteTimer",
      24                 :            :         "InterconnTimer",
      25                 :            :         "NetbiosExpireTimer",
      26                 :            :         "NetworkTimer",
      27                 :            :         "NTPExpireTimer",
      28                 :            :         "ProfileTimer",
      29                 :            :         "RotateTimer",
      30                 :            :         "RemoveConnection",
      31                 :            :         "RPCExpireTimer",
      32                 :            :         "ScheduleTimer",
      33                 :            :         "TableValTimer",
      34                 :            :         "TCPConnectionAttemptTimer",
      35                 :            :         "TCPConnectionDeleteTimer",
      36                 :            :         "TCPConnectionExpireTimer",
      37                 :            :         "TCPConnectionPartialClose",
      38                 :            :         "TCPConnectionResetTimer",
      39                 :            :         "TriggerTimer",
      40                 :            :         "TimerMgrExpireTimer",
      41                 :            : };
      42                 :            : 
      43                 :      57396 : const char* timer_type_to_string(TimerType type)
      44                 :            :         {
      45                 :      57396 :         return TimerNames[type];
      46                 :            :         }
      47                 :            : 
      48                 :          0 : void Timer::Describe(ODesc* d) const
      49                 :            :         {
      50                 :          0 :         d->Add(TimerNames[type]);
      51                 :          0 :         d->Add(" at " );
      52                 :          0 :         d->Add(Time());
      53                 :          0 :         }
      54                 :            : 
      55                 :          0 : bool Timer::Serialize(SerialInfo* info) const
      56                 :            :         {
      57                 :          0 :         return SerialObj::Serialize(info);
      58                 :            :         }
      59                 :            : 
      60                 :          0 : Timer* Timer::Unserialize(UnserialInfo* info)
      61                 :            :         {
      62                 :          0 :         Timer* timer = (Timer*) SerialObj::Unserialize(info, SER_TIMER);
      63         [ #  # ]:          0 :         if ( ! timer )
      64                 :          0 :                 return 0;
      65                 :            : 
      66                 :          0 :         timer_mgr->Add(timer);
      67                 :            : 
      68                 :          0 :         return timer;
      69                 :            :         }
      70                 :            : 
      71                 :          0 : bool Timer::DoSerialize(SerialInfo* info) const
      72                 :            :         {
      73 [ #  # ][ #  # ]:          0 :         DO_SERIALIZE(SER_TIMER, SerialObj);
      74                 :          0 :         char tmp = type;
      75 [ #  # ][ #  # ]:          0 :         return SERIALIZE(tmp) && SERIALIZE(time);
      76                 :            :         }
      77                 :            : 
      78                 :          0 : bool Timer::DoUnserialize(UnserialInfo* info)
      79                 :            :         {
      80         [ #  # ]:          0 :         DO_UNSERIALIZE(SerialObj);
      81                 :            : 
      82                 :            :         char tmp;
      83         [ #  # ]:          0 :         if ( ! UNSERIALIZE(&tmp) )
      84                 :          0 :                 return false;
      85                 :          0 :         type = tmp;
      86                 :            : 
      87                 :          0 :         return UNSERIALIZE(&time);
      88                 :            :         }
      89                 :            : 
      90                 :            : unsigned int TimerMgr::current_timers[NUM_TIMER_TYPES];
      91                 :            : 
      92                 :          1 : TimerMgr::~TimerMgr()
      93                 :            :         {
      94                 :          1 :         DBG_LOG(DBG_TM, "deleting timer mgr %p", this);
      95 [ #  # ][ #  # ]:          1 :         }
                 [ -  + ]
      96                 :            : 
      97                 :      21347 : int TimerMgr::Advance(double arg_t, int max_expire)
      98                 :            :         {
      99         [ +  - ]:      21347 :         DBG_LOG(DBG_TM, "advancing %stimer mgr %p to %.6f",
     100                 :            :                 this == timer_mgr ? "global " : "", this, arg_t);
     101                 :            : 
     102                 :      21347 :         t = arg_t;
     103                 :      21347 :         last_timestamp = 0;
     104                 :      21347 :         num_expired = 0;
     105                 :      21347 :         last_advance = timer_mgr->Time();
     106                 :            : 
     107                 :      21347 :         return DoAdvance(t, max_expire);
     108                 :            :         }
     109                 :            : 
     110                 :            : 
     111                 :          3 : PQ_TimerMgr::PQ_TimerMgr(const Tag& tag) : TimerMgr(tag)
     112                 :            :         {
     113                 :          3 :         q = new PriorityQueue;
     114                 :          3 :         }
     115                 :            : 
     116                 :          1 : PQ_TimerMgr::~PQ_TimerMgr()
     117                 :            :         {
     118 [ +  - ][ #  # ]:          1 :         delete q;
                 [ #  # ]
     119 [ +  - ][ #  # ]:          1 :         }
                 [ #  # ]
     120                 :            : 
     121                 :      29889 : void PQ_TimerMgr::Add(Timer* timer)
     122                 :            :         {
     123                 :      29889 :         DBG_LOG(DBG_TM, "Adding timer %s to TimeMgr %p",
     124                 :            :                         timer_type_to_string(timer->Type()), this);
     125                 :            : 
     126                 :            :         // Add the timer even if it's already expired - that way, if
     127                 :            :         // multiple already-added timers are added, they'll still
     128                 :            :         // execute in sorted order.
     129 [ +  - ][ -  + ]:      29889 :         if ( ! q->Add(timer) )
     130                 :          0 :                 internal_error("out of memory");
     131                 :            : 
     132                 :      29889 :         ++current_timers[timer->Type()];
     133                 :      29889 :         }
     134                 :            : 
     135                 :          2 : void PQ_TimerMgr::Expire()
     136                 :            :         {
     137                 :            :         Timer* timer;
     138         [ +  + ]:         46 :         while ( (timer = Remove()) )
     139                 :            :                 {
     140                 :         44 :                 DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
     141                 :            :                                 timer_type_to_string(timer->Type()), this);
     142                 :         44 :                 timer->Dispatch(t, 1);
     143                 :         44 :                 --current_timers[timer->Type()];
     144         [ +  - ]:         44 :                 delete timer;
     145                 :            :                 }
     146                 :          2 :         }
     147                 :            : 
     148                 :      21347 : int PQ_TimerMgr::DoAdvance(double new_t, int max_expire)
     149                 :            :         {
     150                 :      21347 :         Timer* timer = Top();
     151 [ -  + ][ #  # ]:      48810 :         for ( num_expired = 0; (num_expired < max_expire || max_expire == 0) &&
         [ +  - ][ +  + ]
                 [ +  + ]
     152                 :            :                      timer && timer->Time() <= new_t; ++num_expired )
     153                 :            :                 {
     154                 :      27463 :                 last_timestamp = timer->Time();
     155                 :      27463 :                 --current_timers[timer->Type()];
     156                 :            : 
     157                 :            :                 // Remove it before dispatching, since the dispatch
     158                 :            :                 // can otherwise delete it, and then we won't know
     159                 :            :                 // whether we should delete it too.
     160                 :      27463 :                 (void) Remove();
     161                 :            : 
     162                 :      27463 :                 DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
     163                 :            :                                 timer_type_to_string(timer->Type()), this);
     164                 :      27463 :                 timer->Dispatch(new_t, 0);
     165         [ +  - ]:      27463 :                 delete timer;
     166                 :            : 
     167                 :      27463 :                 timer = Top();
     168                 :            :                 }
     169                 :            : 
     170                 :      21347 :         return num_expired;
     171                 :            :         }
     172                 :            : 
     173                 :       2310 : void PQ_TimerMgr::Remove(Timer* timer)
     174                 :            :         {
     175 [ +  - ][ -  + ]:       2310 :         if ( ! q->Remove(timer) )
     176                 :          0 :                 internal_error("asked to remove a missing timer");
     177                 :            : 
     178                 :       2310 :         --current_timers[timer->Type()];
     179         [ +  - ]:       2310 :         delete timer;
     180                 :       2310 :         }
     181                 :            : 
     182                 :          0 : CQ_TimerMgr::CQ_TimerMgr(const Tag& tag) : TimerMgr(tag)
     183                 :            :         {
     184                 :          0 :         cq = cq_init(60.0, 1.0);
     185   [ #  #  #  # ]:          0 :         if ( ! cq )
     186                 :          0 :                 internal_error("could not initialize calendar queue");
     187                 :          0 :         }
     188                 :            : 
     189                 :          0 : CQ_TimerMgr::~CQ_TimerMgr()
     190                 :            :         {
     191                 :          0 :         cq_destroy(cq);
     192 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
     193                 :            : 
     194                 :          0 : void CQ_TimerMgr::Add(Timer* timer)
     195                 :            :         {
     196                 :          0 :         DBG_LOG(DBG_TM, "Adding timer %s to TimeMgr %p",
     197                 :            :                         timer_type_to_string(timer->Type()), this);
     198                 :            : 
     199                 :            :         // Add the timer even if it's already expired - that way, if
     200                 :            :         // multiple already-added timers are added, they'll still
     201                 :            :         // execute in sorted order.
     202                 :          0 :         double t = timer->Time();
     203                 :            : 
     204         [ #  # ]:          0 :         if ( t <= 0.0 )
     205                 :            :                 // Illegal time, which cq_enqueue won't like.  For our
     206                 :            :                 // purposes, just treat it as an old time that's already
     207                 :            :                 // expired.
     208                 :          0 :                 t = network_time;
     209                 :            : 
     210         [ #  # ]:          0 :         if ( cq_enqueue(cq, t, timer) < 0 )
     211                 :          0 :                 internal_error("problem queueing timer");
     212                 :            : 
     213                 :          0 :         ++current_timers[timer->Type()];
     214                 :          0 :         }
     215                 :            : 
     216                 :          0 : void CQ_TimerMgr::Expire()
     217                 :            :         {
     218                 :          0 :         double huge_t = 1e20;   // larger than any Unix timestamp
     219         [ #  # ]:          0 :         for ( Timer* timer = (Timer*) cq_dequeue(cq, huge_t);
     220                 :            :               timer; timer = (Timer*) cq_dequeue(cq, huge_t) )
     221                 :            :                 {
     222                 :          0 :                 DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
     223                 :            :                                 timer_type_to_string(timer->Type()), this);
     224                 :          0 :                 timer->Dispatch(huge_t, 1);
     225                 :          0 :                 --current_timers[timer->Type()];
     226         [ #  # ]:          0 :                 delete timer;
     227                 :            :                 }
     228                 :          0 :         }
     229                 :            : 
     230                 :          0 : int CQ_TimerMgr::DoAdvance(double new_t, int max_expire)
     231                 :            :         {
     232                 :            :         Timer* timer;
     233 [ #  # ][ #  # ]:          0 :         while ( (num_expired < max_expire || max_expire == 0) &&
         [ #  # ][ #  # ]
     234                 :            :                 (timer = (Timer*) cq_dequeue(cq, new_t)) )
     235                 :            :                 {
     236                 :          0 :                 last_timestamp = timer->Time();
     237                 :          0 :                 DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
     238                 :            :                                 timer_type_to_string(timer->Type()), this);
     239                 :          0 :                 timer->Dispatch(new_t, 0);
     240                 :          0 :                 --current_timers[timer->Type()];
     241         [ #  # ]:          0 :                 delete timer;
     242                 :          0 :                 ++num_expired;
     243                 :            :                 }
     244                 :            : 
     245                 :          0 :         return num_expired;
     246                 :            :         }
     247                 :            : 
     248                 :          0 : unsigned int CQ_TimerMgr::MemoryUsage() const
     249                 :            :         {
     250                 :            :         // FIXME.
     251                 :          0 :         return 0;
     252                 :            :         }
     253                 :            : 
     254                 :          0 : void CQ_TimerMgr::Remove(Timer* timer)
     255                 :            :         {
     256                 :            :         // This may fail if we cancel a timer which has already been removed.
     257                 :            :         // That's ok, but then we mustn't delete the timer.
     258         [ #  # ]:          0 :         if ( cq_remove(cq, timer->Time(), timer) )
     259                 :            :                 {
     260                 :          0 :                 --current_timers[timer->Type()];
     261         [ #  # ]:          0 :                 delete timer;
     262                 :            :                 }
     263 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8