mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 01:28:20 +00:00
Initial import of svn+ssh:://svn.icir.org/bro/trunk/bro as of r7088
This commit is contained in:
commit
61757ac78b
1383 changed files with 380824 additions and 0 deletions
263
src/Timer.cc
Normal file
263
src/Timer.cc
Normal file
|
@ -0,0 +1,263 @@
|
|||
// $Id: Timer.cc 6219 2008-10-01 05:39:07Z vern $
|
||||
//
|
||||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "Timer.h"
|
||||
#include "Desc.h"
|
||||
#include "Serializer.h"
|
||||
|
||||
// Names of timers in same order than in TimerType.
|
||||
const char* TimerNames[] = {
|
||||
"BackdoorTimer",
|
||||
"BreakpointTimer",
|
||||
"ConnectionDeleteTimer",
|
||||
"ConnectionExpireTimer",
|
||||
"ConnectionInactivityTimer",
|
||||
"ConnectionStatusUpdateTimer",
|
||||
"DNSExpireTimer",
|
||||
"FragTimer",
|
||||
"IncrementalSendTimer",
|
||||
"IncrementalWriteTimer",
|
||||
"InterconnTimer",
|
||||
"NetbiosExpireTimer",
|
||||
"NetworkTimer",
|
||||
"NTPExpireTimer",
|
||||
"ProfileTimer",
|
||||
"RotateTimer",
|
||||
"RemoveConnection",
|
||||
"RPCExpireTimer",
|
||||
"ScheduleTimer",
|
||||
"TableValTimer",
|
||||
"TCPConnectionAttemptTimer",
|
||||
"TCPConnectionDeleteTimer",
|
||||
"TCPConnectionExpireTimer",
|
||||
"TCPConnectionPartialClose",
|
||||
"TCPConnectionResetTimer",
|
||||
"TriggerTimer",
|
||||
"TimerMgrExpireTimer",
|
||||
};
|
||||
|
||||
const char* timer_type_to_string(TimerType type)
|
||||
{
|
||||
return TimerNames[type];
|
||||
}
|
||||
|
||||
void Timer::Describe(ODesc* d) const
|
||||
{
|
||||
d->Add(TimerNames[type]);
|
||||
d->Add(" at " );
|
||||
d->Add(Time());
|
||||
}
|
||||
|
||||
bool Timer::Serialize(SerialInfo* info) const
|
||||
{
|
||||
return SerialObj::Serialize(info);
|
||||
}
|
||||
|
||||
Timer* Timer::Unserialize(UnserialInfo* info)
|
||||
{
|
||||
Timer* timer = (Timer*) SerialObj::Unserialize(info, SER_TIMER);
|
||||
if ( ! timer )
|
||||
return 0;
|
||||
|
||||
timer_mgr->Add(timer);
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
bool Timer::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_TIMER, SerialObj);
|
||||
char tmp = type;
|
||||
return SERIALIZE(tmp) && SERIALIZE(time);
|
||||
}
|
||||
|
||||
bool Timer::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(SerialObj);
|
||||
|
||||
char tmp;
|
||||
if ( ! UNSERIALIZE(&tmp) )
|
||||
return false;
|
||||
type = tmp;
|
||||
|
||||
return UNSERIALIZE(&time);
|
||||
}
|
||||
|
||||
unsigned int TimerMgr::current_timers[NUM_TIMER_TYPES];
|
||||
|
||||
TimerMgr::~TimerMgr()
|
||||
{
|
||||
DBG_LOG(DBG_TM, "deleting timer mgr %p", this);
|
||||
}
|
||||
|
||||
int TimerMgr::Advance(double arg_t, int max_expire)
|
||||
{
|
||||
DBG_LOG(DBG_TM, "advancing %stimer mgr %p to %.6f",
|
||||
this == timer_mgr ? "global " : "", this, arg_t);
|
||||
|
||||
t = arg_t;
|
||||
last_timestamp = 0;
|
||||
num_expired = 0;
|
||||
last_advance = timer_mgr->Time();
|
||||
|
||||
return DoAdvance(t, max_expire);
|
||||
}
|
||||
|
||||
|
||||
PQ_TimerMgr::PQ_TimerMgr(const Tag& tag) : TimerMgr(tag)
|
||||
{
|
||||
q = new PriorityQueue;
|
||||
}
|
||||
|
||||
PQ_TimerMgr::~PQ_TimerMgr()
|
||||
{
|
||||
delete q;
|
||||
}
|
||||
|
||||
void PQ_TimerMgr::Add(Timer* timer)
|
||||
{
|
||||
DBG_LOG(DBG_TM, "Adding timer %s to TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
|
||||
// Add the timer even if it's already expired - that way, if
|
||||
// multiple already-added timers are added, they'll still
|
||||
// execute in sorted order.
|
||||
if ( ! q->Add(timer) )
|
||||
internal_error("out of memory");
|
||||
|
||||
++current_timers[timer->Type()];
|
||||
}
|
||||
|
||||
void PQ_TimerMgr::Expire()
|
||||
{
|
||||
Timer* timer;
|
||||
while ( (timer = Remove()) )
|
||||
{
|
||||
DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
timer->Dispatch(t, 1);
|
||||
--current_timers[timer->Type()];
|
||||
delete timer;
|
||||
}
|
||||
}
|
||||
|
||||
int PQ_TimerMgr::DoAdvance(double new_t, int max_expire)
|
||||
{
|
||||
Timer* timer = Top();
|
||||
for ( num_expired = 0; (num_expired < max_expire || max_expire == 0) &&
|
||||
timer && timer->Time() <= new_t; ++num_expired )
|
||||
{
|
||||
last_timestamp = timer->Time();
|
||||
--current_timers[timer->Type()];
|
||||
|
||||
// Remove it before dispatching, since the dispatch
|
||||
// can otherwise delete it, and then we won't know
|
||||
// whether we should delete it too.
|
||||
(void) Remove();
|
||||
|
||||
DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
timer->Dispatch(new_t, 0);
|
||||
delete timer;
|
||||
|
||||
timer = Top();
|
||||
}
|
||||
|
||||
return num_expired;
|
||||
}
|
||||
|
||||
void PQ_TimerMgr::Remove(Timer* timer)
|
||||
{
|
||||
if ( ! q->Remove(timer) )
|
||||
internal_error("asked to remove a missing timer");
|
||||
|
||||
--current_timers[timer->Type()];
|
||||
delete timer;
|
||||
}
|
||||
|
||||
CQ_TimerMgr::CQ_TimerMgr(const Tag& tag) : TimerMgr(tag)
|
||||
{
|
||||
cq = cq_init(60.0, 1.0);
|
||||
if ( ! cq )
|
||||
internal_error("could not initialize calendar queue");
|
||||
}
|
||||
|
||||
CQ_TimerMgr::~CQ_TimerMgr()
|
||||
{
|
||||
cq_destroy(cq);
|
||||
}
|
||||
|
||||
void CQ_TimerMgr::Add(Timer* timer)
|
||||
{
|
||||
DBG_LOG(DBG_TM, "Adding timer %s to TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
|
||||
// Add the timer even if it's already expired - that way, if
|
||||
// multiple already-added timers are added, they'll still
|
||||
// execute in sorted order.
|
||||
double t = timer->Time();
|
||||
|
||||
if ( t <= 0.0 )
|
||||
// Illegal time, which cq_enqueue won't like. For our
|
||||
// purposes, just treat it as an old time that's already
|
||||
// expired.
|
||||
t = network_time;
|
||||
|
||||
if ( cq_enqueue(cq, t, timer) < 0 )
|
||||
internal_error("problem queueing timer");
|
||||
|
||||
++current_timers[timer->Type()];
|
||||
}
|
||||
|
||||
void CQ_TimerMgr::Expire()
|
||||
{
|
||||
double huge_t = 1e20; // larger than any Unix timestamp
|
||||
for ( Timer* timer = (Timer*) cq_dequeue(cq, huge_t);
|
||||
timer; timer = (Timer*) cq_dequeue(cq, huge_t) )
|
||||
{
|
||||
DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
timer->Dispatch(huge_t, 1);
|
||||
--current_timers[timer->Type()];
|
||||
delete timer;
|
||||
}
|
||||
}
|
||||
|
||||
int CQ_TimerMgr::DoAdvance(double new_t, int max_expire)
|
||||
{
|
||||
Timer* timer;
|
||||
while ( (num_expired < max_expire || max_expire == 0) &&
|
||||
(timer = (Timer*) cq_dequeue(cq, new_t)) )
|
||||
{
|
||||
last_timestamp = timer->Time();
|
||||
DBG_LOG(DBG_TM, "Dispatching timer %s in TimeMgr %p",
|
||||
timer_type_to_string(timer->Type()), this);
|
||||
timer->Dispatch(new_t, 0);
|
||||
--current_timers[timer->Type()];
|
||||
delete timer;
|
||||
++num_expired;
|
||||
}
|
||||
|
||||
return num_expired;
|
||||
}
|
||||
|
||||
unsigned int CQ_TimerMgr::MemoryUsage() const
|
||||
{
|
||||
// FIXME.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CQ_TimerMgr::Remove(Timer* timer)
|
||||
{
|
||||
// This may fail if we cancel a timer which has already been removed.
|
||||
// That's ok, but then we mustn't delete the timer.
|
||||
if ( cq_remove(cq, timer->Time(), timer) )
|
||||
{
|
||||
--current_timers[timer->Type()];
|
||||
delete timer;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue