Retrieve and reuse Time::now() at most twice per SIPEngine::getEvent()

Avoids making too many calls to gettimeofday() when there are many SIP transactions.


git-svn-id: http://yate.null.ro/svn/yate/trunk@5254 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2012-09-11 10:27:56 +00:00
parent 64e3c4b224
commit 8aa902352c
3 changed files with 33 additions and 28 deletions

View File

@ -278,31 +278,31 @@ bool SIPEngine::process()
SIPEvent* SIPEngine::getEvent()
{
Lock lock(this);
ObjList* l = &m_transList;
for (; l; l = l->next()) {
ObjList* l = m_transList.skipNull();
if (!l)
return 0;
u_int64_t time = Time::now();
for (; l; l = l->skipNext()) {
SIPTransaction* t = static_cast<SIPTransaction*>(l->get());
if (t) {
SIPEvent* e = t->getEvent(true);
if (e) {
DDebug(this,DebugInfo,"Got pending event %p (state %s) from transaction %p [%p]",
e,SIPTransaction::stateName(e->getState()),t,this);
if (t->getState() == SIPTransaction::Invalid)
m_transList.remove(t);
return e;
}
SIPEvent* e = t->getEvent(true,time);
if (e) {
DDebug(this,DebugInfo,"Got pending event %p (state %s) from transaction %p [%p]",
e,SIPTransaction::stateName(e->getState()),t,this);
if (t->getState() == SIPTransaction::Invalid)
m_transList.remove(t);
return e;
}
}
for (l = &m_transList; l; l = l->next()) {
time = Time::now();
for (l = m_transList.skipNull(); l; l = l->skipNext()) {
SIPTransaction* t = static_cast<SIPTransaction*>(l->get());
if (t) {
SIPEvent* e = t->getEvent(false);
if (e) {
DDebug(this,DebugInfo,"Got event %p (state %s) from transaction %p [%p]",
e,SIPTransaction::stateName(e->getState()),t,this);
if (t->getState() == SIPTransaction::Invalid)
m_transList.remove(t);
return e;
}
SIPEvent* e = t->getEvent(false,time);
if (e) {
DDebug(this,DebugInfo,"Got event %p (state %s) from transaction %p [%p]",
e,SIPTransaction::stateName(e->getState()),t,this);
if (t->getState() == SIPTransaction::Invalid)
m_transList.remove(t);
return e;
}
}
return 0;

View File

@ -245,7 +245,7 @@ void SIPTransaction::setTimeout(u_int64_t delay, unsigned int count)
#endif
}
SIPEvent* SIPTransaction::getEvent(bool pendingOnly)
SIPEvent* SIPTransaction::getEvent(bool pendingOnly, u_int64_t time)
{
SIPEvent *e = 0;
@ -264,11 +264,15 @@ SIPEvent* SIPTransaction::getEvent(bool pendingOnly)
return 0;
int timeout = -1;
if (m_timeout && (Time::now() >= m_timeout)) {
timeout = --m_timeouts;
m_delay *= 2; // exponential back-off
m_timeout = (m_timeouts) ? Time::now() + m_delay : 0;
DDebug(getEngine(),DebugAll,"SIPTransaction fired timer #%d [%p]",timeout,this);
if (m_timeout) {
if (!time)
time = Time::now();
if (time >= m_timeout) {
timeout = --m_timeouts;
m_delay *= 2; // exponential back-off
m_timeout = (m_timeouts) ? time + m_delay : 0;
DDebug(getEngine(),DebugAll,"SIPTransaction fired timer #%d [%p]",timeout,this);
}
}
e = isOutgoing() ? getClientEvent(m_state,timeout) : getServerEvent(m_state,timeout);

View File

@ -835,9 +835,10 @@ public:
* the more specific protected version.
* You may override this method if you need processing of invalid states.
* @param pendingOnly True to only return outgoing and pending events
* @param time Time to use in timeouts, zero to use system time
* @return A newly allocated event or NULL if none is needed
*/
virtual SIPEvent* getEvent(bool pendingOnly = false);
virtual SIPEvent* getEvent(bool pendingOnly = false, u_int64_t time = 0);
/**
* Checks if a response message can be sent