[Freeswitch-svn] [commit] r8287 - freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta

Freeswitch SVN mikej at freeswitch.org
Wed May 7 08:28:33 EDT 2008


Author: mikej
Date: Wed May  7 08:28:33 2008
New Revision: 8287

Modified:
   freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
   freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h

Log:
Tue May  6 17:00:19 EDT 2008  first.last at nokia.com
  * nta.c: use consistently uint32_t when handling millisecond timers inside nta
  
  The timer handling failed miserably on 64-bit platforms each time uint32_t
  counter for milliseconds wrapped around.



Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c	(original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta.c	Wed May  7 08:28:33 2008
@@ -734,7 +734,7 @@
 void agent_timer(su_root_magic_t *rm, su_timer_t *timer, nta_agent_t *agent)
 {
   su_time_t stamp = su_now();
-  su_duration_t now = su_time_ms(stamp), next;
+  uint32_t now = su_time_ms(stamp), next, latest;
 
   now += now == 0;
 
@@ -752,10 +752,11 @@
   agent->sa_in_timer = 0;
 
   /* Calculate next timeout */
-  next = now + SU_DURATION_MAX;
+  next = latest = now + NTA_TIME_MAX + 1;
 
 #define NEXT_TIMEOUT(next, p, f, now) \
-  (void)(p && p->f - (next) < 0 && ((next) = (p->f - (now) > 0 ? p->f : (now))))
+  (void)(p && (int32_t)(p->f - (next)) < 0 && \
+	 ((next) = ((int32_t)(p->f - (now)) > 0 ? p->f : (now))))
 
   NEXT_TIMEOUT(next, agent->sa_out.re_list, orq_retry, now);
   NEXT_TIMEOUT(next, agent->sa_out.inv_completed->q_head, orq_timeout, now);
@@ -776,8 +777,8 @@
 
 #undef NEXT_TIMEOUT
 
-  if (next == now + SU_DURATION_MAX) {
-    /* Do not set timer */
+  if (next == latest) {
+    /* Do not set timer? */
     SU_DEBUG_9(("nta: timer not set\n"));
     assert(!agent->sa_out.completed->q_head);
     assert(!agent->sa_out.trying->q_head);
@@ -800,6 +801,22 @@
   su_timer_set_at(timer, agent_timer, agent, su_time_add(stamp, next - now));
 }
 
+/** Add uin32_t milliseconds to the time. */
+static su_time_t add_milliseconds(su_time_t t0, uint32_t ms)
+{
+  unsigned long sec = ms / 1000, usec = (ms % 1000) * 1000;
+
+  t0.tv_usec += usec;
+  t0.tv_sec += sec;
+
+  if (t0.tv_usec >= 1000000) {
+    t0.tv_sec += 1;
+    t0.tv_usec -= 1000000;
+  }
+
+  return t0;
+}
+
 /** Calculate nonzero value for timeout.
  *
  * Sets or adjusts agent timer when needed.
@@ -808,25 +825,25 @@
  * @retval timeout (millisecond counter) otherwise
  */
 static
-su_duration_t set_timeout(nta_agent_t *agent, su_duration_t offset)
+uint32_t set_timeout(nta_agent_t *agent, uint32_t offset)
 {
   su_time_t now;
-  su_duration_t next, ms;
+  uint32_t next, ms;
 
   if (offset == 0)
     return 0;
 
-  if (agent->sa_millisec) /* Avoid expensive call to su_timer_ms() */
+  if (agent->sa_millisec) /* Avoid expensive call to su_now() */
     now = agent->sa_now, ms = agent->sa_millisec;
   else
-    now = su_now(), ms = (su_duration_t)su_time_ms(now);
+    now = su_now(), ms = su_time_ms(now);
   
   next = ms + offset; if (next == 0) next = 1;
 
-  if (agent->sa_in_timer)
+  if (agent->sa_in_timer)	/* Currently executing timer */
     return next;
 
-  if (agent->sa_next == 0 || agent->sa_next - next - 5L > 0) {
+  if (agent->sa_next == 0 || (int32_t)(agent->sa_next - next - 5L) > 0) {
     /* Set timer */
     if (agent->sa_next)
       SU_DEBUG_9(("nta: timer %s to %ld ms\n", "shortened", (long)offset));
@@ -834,7 +851,7 @@
       SU_DEBUG_9(("nta: timer %s to %ld ms\n", "set", (long)offset));
       
     su_timer_set_at(agent->sa_timer, agent_timer, agent, 
-		    su_time_add(now, offset));
+		    add_milliseconds(now, offset));
     agent->sa_next = next;
   }
 
@@ -1093,7 +1110,7 @@
   }
 
   if (maxsize == 0) maxsize = 2 * 1024 * 1024;
-  if (maxsize > NTA_TIME_MAX) maxsize = NTA_TIME_MAX;
+  if (maxsize > UINT32_MAX) maxsize = UINT32_MAX;
   agent->sa_maxsize = maxsize;
 
   if (max_proceeding == 0) max_proceeding = SIZE_MAX;
@@ -4522,7 +4539,7 @@
 su_inline int incoming_is_queued(nta_incoming_t const *irq);
 su_inline void incoming_queue(incoming_queue_t *queue, nta_incoming_t *);
 su_inline void incoming_remove(nta_incoming_t *irq);
-su_inline void incoming_set_timer(nta_incoming_t *, unsigned interval);
+su_inline void incoming_set_timer(nta_incoming_t *, uint32_t interval);
 su_inline void incoming_reset_timer(nta_incoming_t *);
 su_inline size_t incoming_mass_destroy(nta_agent_t *, incoming_queue_t *);
 
@@ -4856,10 +4873,10 @@
 static void
 incoming_queue_adjust(nta_agent_t *sa, 
 		      incoming_queue_t *queue, 
-		      unsigned timeout)
+		      uint32_t timeout)
 {
   nta_incoming_t *irq;
-  su_duration_t latest;
+  uint32_t latest;
 
   if (timeout >= queue->q_timeout || !queue->q_head) {
     queue->q_timeout = timeout;
@@ -4869,7 +4886,7 @@
   latest = set_timeout(sa, queue->q_timeout = timeout);
 
   for (irq = queue->q_head; irq; irq = irq->irq_next) {
-    if (irq->irq_timeout - latest > 0)
+    if ((int32_t)(irq->irq_timeout - latest) > 0)
       irq->irq_timeout = latest;
   }
 }
@@ -4934,7 +4951,7 @@
 }
 
 su_inline
-void incoming_set_timer(nta_incoming_t *irq, unsigned interval)
+void incoming_set_timer(nta_incoming_t *irq, uint32_t interval)
 {
   nta_incoming_t **rq;
   
@@ -4958,10 +4975,10 @@
 
   rq = irq->irq_agent->sa_in.re_t1;
 
-  if (!(*rq) || (*rq)->irq_retry - irq->irq_retry > 0)
+  if (!(*rq) || (int32_t)((*rq)->irq_retry - irq->irq_retry) > 0)
     rq = &irq->irq_agent->sa_in.re_list;
 
-  while (*rq && (*rq)->irq_retry - irq->irq_retry <= 0)
+  while (*rq && (int32_t)((*rq)->irq_retry - irq->irq_retry) <= 0)
     rq = &(*rq)->irq_rnext;
 
   if ((irq->irq_rnext = *rq))
@@ -6188,7 +6205,7 @@
 /** @internal Timer routine for the incoming request. */
 static void incoming_timer(nta_agent_t *sa)
 {
-  su_duration_t now = sa->sa_millisec;
+  uint32_t now = sa->sa_millisec;
   nta_incoming_t *irq, *irq_next;
   size_t retransmitted = 0, timeout = 0, terminated = 0, destroyed = 0;
   size_t unconfirmed = 
@@ -6205,7 +6222,7 @@
 
   /* Handle retry queue */
   while ((irq = sa->sa_in.re_list)) {
-    if (irq->irq_retry - now > 0)
+    if ((int32_t)(irq->irq_retry - now) > 0)
       break;
     if (retransmitted >= timer_max_retransmit)
       break;
@@ -6286,7 +6303,7 @@
     assert(irq->irq_status < 200);
     assert(irq->irq_timeout);
 
-    if (irq->irq_timeout - now > 0)
+    if ((int32_t)(irq->irq_timeout - now) > 0)
       break;
     if (timeout >= timer_max_timeout)
       break;
@@ -6306,7 +6323,7 @@
     assert(irq->irq_timeout);
     assert(irq->irq_method == sip_method_invite);
 
-    if (irq->irq_timeout - now > 0 || 
+    if ((int32_t)(irq->irq_timeout - now) > 0 ||
 	timeout >= timer_max_timeout || 
 	terminated >= timer_max_terminate)
       break;
@@ -6334,7 +6351,8 @@
     assert(irq->irq_status >= 200);
     assert(irq->irq_method == sip_method_invite);
 
-    if (irq->irq_timeout - now > 0 || terminated >= timer_max_terminate)
+    if ((int32_t)(irq->irq_timeout - now) > 0 ||
+	terminated >= timer_max_terminate)
       break;
     
     /* Timer I */
@@ -6355,7 +6373,8 @@
     assert(irq->irq_timeout);
     assert(irq->irq_method != sip_method_invite);
 
-    if (irq->irq_timeout - now > 0 || terminated >= timer_max_terminate)
+    if ((int32_t)(irq->irq_timeout - now) > 0 ||
+	terminated >= timer_max_terminate)
       break;
 
     /* Timer J */
@@ -6448,24 +6467,24 @@
 su_inline void outgoing_queue(outgoing_queue_t *queue, 
 				  nta_outgoing_t *orq);
 su_inline void outgoing_remove(nta_outgoing_t *orq);
-su_inline void outgoing_set_timer(nta_outgoing_t *orq, unsigned interval);
+su_inline void outgoing_set_timer(nta_outgoing_t *orq, uint32_t interval);
 su_inline void outgoing_reset_timer(nta_outgoing_t *orq);
 static size_t outgoing_timer_dk(outgoing_queue_t *q, 
 				char const *timer, 
-				su_duration_t now);
+				uint32_t now);
 static size_t outgoing_timer_bf(outgoing_queue_t *q, 
 				char const *timer, 
-				su_duration_t now);
+				uint32_t now);
 static size_t outgoing_timer_c(outgoing_queue_t *q, 
 			       char const *timer, 
-			       su_duration_t now);
+			       uint32_t now);
 
 static void outgoing_ack(nta_outgoing_t *orq, sip_t *sip);
 static msg_t *outgoing_ackmsg(nta_outgoing_t *, sip_method_t, char const *,
 			      tagi_t const *tags);
 static void outgoing_retransmit(nta_outgoing_t *orq);
 static void outgoing_trying(nta_outgoing_t *orq);
-static void outgoing_timeout(nta_outgoing_t *orq, su_duration_t now);
+static void outgoing_timeout(nta_outgoing_t *orq, uint32_t now);
 static int outgoing_complete(nta_outgoing_t *orq);
 static int outgoing_terminate(nta_outgoing_t *orq);
 static size_t outgoing_mass_destroy(nta_agent_t *sa, outgoing_queue_t *q);
@@ -7707,7 +7726,7 @@
 		      unsigned timeout)
 {
   nta_outgoing_t *orq;
-  su_duration_t latest;
+  uint32_t latest;
 
   if (timeout >= queue->q_timeout || !queue->q_head) {
     queue->q_timeout = timeout;
@@ -7718,7 +7737,7 @@
 
   for (orq = queue->q_head; orq; orq = orq->orq_next) {
     if (orq->orq_timeout == 0 ||
-	orq->orq_timeout - latest > 0)
+	(int32_t)(orq->orq_timeout - latest) > 0)
       orq->orq_timeout = latest;
   }
 }
@@ -7788,7 +7807,7 @@
  * Set the retry timer (B/D) on the outgoing request (client transaction).
  */
 su_inline
-void outgoing_set_timer(nta_outgoing_t *orq, unsigned interval)
+void outgoing_set_timer(nta_outgoing_t *orq, uint32_t interval)
 {
   nta_outgoing_t **rq;
   
@@ -7815,10 +7834,10 @@
   /* Shortcut into queue at SIP T1 */
   rq = orq->orq_agent->sa_out.re_t1;
 
-  if (!(*rq) || (*rq)->orq_retry - orq->orq_retry > 0)
+  if (!(*rq) || (int32_t)((*rq)->orq_retry - orq->orq_retry) > 0)
     rq = &orq->orq_agent->sa_out.re_list;
 
-  while (*rq && (*rq)->orq_retry - orq->orq_retry <= 0)
+  while (*rq && (int32_t)((*rq)->orq_retry - orq->orq_retry) <= 0)
     rq = &(*rq)->orq_rnext;
 
   if ((orq->orq_rnext = *rq))
@@ -7966,7 +7985,7 @@
  */
 static void outgoing_timer(nta_agent_t *sa)
 {
-  su_duration_t now = sa->sa_millisec;
+  uint32_t now = sa->sa_millisec;
   nta_outgoing_t *orq;
   outgoing_queue_t rq[1];
   size_t retransmitted = 0, terminated = 0, timeout = 0, destroyed;
@@ -7980,7 +7999,7 @@
   outgoing_queue_init(sa->sa_out.free = rq, 0);
 
   while ((orq = sa->sa_out.re_list)) {
-    if (orq->orq_retry - now > 0)
+    if ((int32_t)(orq->orq_retry) - now > 0)
       break;
     if (retransmitted >= timer_max_retransmit)
       break;
@@ -8076,13 +8095,14 @@
 static
 size_t outgoing_timer_bf(outgoing_queue_t *q, 
 			 char const *timer, 
-			 su_duration_t now)
+			 uint32_t now)
 {
   nta_outgoing_t *orq;
   size_t timeout = 0;
 
   while ((orq = q->q_head)) {
-    if (orq->orq_timeout - now > 0 || timeout >= timer_max_timeout)
+    if ((int32_t)(orq->orq_timeout - now) > 0 ||
+	timeout >= timer_max_timeout)
       break;
 
     timeout++;
@@ -8097,7 +8117,7 @@
     else
       outgoing_terminate(orq);
 
-    assert(q->q_head != orq || orq->orq_timeout - now > 0);
+    assert(q->q_head != orq || (int32_t)(orq->orq_timeout - now) > 0);
   }
 
   return timeout;
@@ -8107,7 +8127,7 @@
 static
 size_t outgoing_timer_c(outgoing_queue_t *q, 
 			char const *timer, 
-			su_duration_t now)
+			uint32_t now)
 {
   nta_outgoing_t *orq;
   size_t timeout = 0;
@@ -8116,7 +8136,7 @@
     return 0;
 
   while ((orq = q->q_head)) {
-    if (orq->orq_timeout - now > 0 || timeout >= timer_max_timeout)
+    if ((int32_t)(orq->orq_timeout - now) > 0 || timeout >= timer_max_timeout)
       break;
 
     timeout++;
@@ -8136,7 +8156,7 @@
 }
 
 /** @internal Signal transaction timeout to the application. */
-void outgoing_timeout(nta_outgoing_t *orq, su_duration_t now)
+void outgoing_timeout(nta_outgoing_t *orq, uint32_t now)
 {
   nta_outgoing_t *cancel;
 
@@ -8184,13 +8204,14 @@
 static
 size_t outgoing_timer_dk(outgoing_queue_t *q, 
 			 char const *timer, 
-			 su_duration_t now)
+			 uint32_t now)
 {
   nta_outgoing_t *orq;
   size_t terminated = 0;
 
   while ((orq = q->q_head)) {
-    if (orq->orq_timeout - now > 0 || terminated >= timer_max_terminate)
+    if ((int32_t)(orq->orq_timeout - now) > 0 ||
+	terminated >= timer_max_terminate)
       break;
 
     terminated++;

Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h	(original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nta/nta_internal.h	Wed May  7 08:28:33 2008
@@ -102,9 +102,9 @@
   nta_update_magic_t   *sa_update_magic;
   nta_update_tport_f   *sa_update_tport;
 
-  su_duration_t         sa_next; /**< Timestamp for next agent_timer. */
   su_time_t             sa_now;	 /**< Timestamp in microsecond resolution. */
-  uint32_t              sa_millisec; /**< Timestamp in milliseconds resolution. */
+  uint32_t              sa_next; /**< Timestamp for next agent_timer. */
+  uint32_t              sa_millisec; /**< Timestamp in milliseconds. */
 
   uint32_t              sa_nw_updates; /* Shall we enable network detector? */
 
@@ -419,8 +419,8 @@
   sip_timestamp_t      *irq_timestamp;
   su_time_t             irq_received;
 
-  su_duration_t       	irq_timeout;    /**< Timer H, I, J */
-  su_duration_t       	irq_retry;      /**< Timer G */
+  uint32_t       	irq_timeout;    /**< Timer H, I, J */
+  uint32_t       	irq_retry;      /**< Timer G */
   unsigned short      	irq_interval;	/**< Next timer  */
 
   short               	irq_status;
@@ -499,8 +499,8 @@
   su_time_t             orq_sent;       /**< When request was sent? */
   unsigned              orq_delay;      /**< RTT estimate */
 
-  su_duration_t         orq_retry;	/**< Timer A, E */
-  su_duration_t       	orq_timeout;	/**< Timer B, D, F, K */
+  uint32_t		orq_retry;	/**< Timer A, E */
+  uint32_t		orq_timeout;	/**< Timer B, D, F, K */
 
   unsigned short      	orq_interval;	/**< Next timer A/E */
 



More information about the Freeswitch-svn mailing list