コード例 #1
0
/** Keepalive timer. */
void tport_keepalive_timer(tport_t *self, su_time_t now)
{
  unsigned timeout = self->tp_params->tpp_pingpong;

  if (timeout != 0) {
    if (self->tp_ptime.tv_sec && !self->tp_recv_close &&
	su_time_cmp(su_time_add(self->tp_ptime, timeout), now) < 0) {
      SU_DEBUG_3(("%s(%p): %s to " TPN_FORMAT "%s\n",
		  __func__, (void *)self,
		  "closing connection", TPN_ARGS(self->tp_name),
		  " because of PONG timeout"));
      tport_error_report(self, EPIPE, NULL);
      if (!self->tp_closed)
	tport_close(self);
      return;
    }
  }

  timeout = self->tp_params->tpp_keepalive;

  if (timeout != 0 && timeout != UINT_MAX) {
    if (su_time_cmp(su_time_add(self->tp_ktime, timeout), now) < 0) {
      tport_tcp_ping(self, now);
    }
  }
}
コード例 #2
0
/** Calculate next timeout for keepalive */
int tport_next_keepalive(tport_t *self,
			 su_time_t *return_target,
			 char const **return_why)
{
  /* Keepalive timer */
  unsigned timeout = self->tp_params->tpp_keepalive;

  if (timeout != 0 && timeout != UINT_MAX) {
    if (!tport_has_queued(self)) {
      su_time_t ntime = su_time_add(self->tp_ktime, timeout);
      if (su_time_cmp(ntime, *return_target) < 0)
	*return_target = ntime, *return_why = "keepalive";
    }
  }

  timeout = self->tp_params->tpp_pingpong;
  if (timeout != 0) {
    if (self->tp_ptime.tv_sec && !self->tp_recv_close) {
      su_time_t ntime = su_time_add(self->tp_ptime, timeout);
      if (su_time_cmp(ntime, *return_target) < 0)
	*return_target = ntime, *return_why = "waiting for pong";
    }
  }

  return 0;
}
コード例 #3
0
/** Timeout timer if receive is incomplete */
void tport_recv_timeout_timer(tport_t *self, su_time_t now)
{
  unsigned timeout = self->tp_params->tpp_timeout;

  if (timeout < INT_MAX) {
    if (self->tp_msg &&
	su_time_cmp(su_time_add(self->tp_rtime, timeout), now) < 0) {
      msg_t *msg = self->tp_msg;
      msg_set_streaming(msg, (enum msg_streaming_status)0);
      msg_set_flags(msg, MSG_FLG_ERROR | MSG_FLG_TRUNC | MSG_FLG_TIMEOUT);
      tport_deliver(self, msg, NULL, NULL, now);
      self->tp_msg = NULL;
    }

#if 0
    /* Send timeout */
    if (tport_has_queued(self) &&
	su_time_cmp(su_time_add(self->tp_stime, timeout), now) < 0) {
      stime = su_time_add(self->tp_stime, self->tp_params->tpp_timeout);
      if (su_time_cmp(stime, target) < 0)
	target = stime;
    }
#endif
  }
}
コード例 #4
0
/** Calculate timeout if receive is incomplete. */
int tport_next_recv_timeout(tport_t *self,
			    su_time_t *return_target,
			    char const **return_why)
{
  unsigned timeout = self->tp_params->tpp_timeout;

  if (timeout < INT_MAX) {
    /* Recv timeout */
    if (self->tp_msg) {
      su_time_t ntime = su_time_add(self->tp_rtime, timeout);
      if (su_time_cmp(ntime, *return_target) < 0)
	*return_target = ntime, *return_why = "recv timeout";
    }

#if 0
    /* Send timeout */
    if (tport_has_queued(self)) {
      su_time_t ntime = su_time_add(self->tp_stime, timeout);
      if (su_time_cmp(ntime, *return_target) < 0)
	*return_target = ntime, *return_why = "send timeout";
    }
#endif
  }

  return 0;
}
コード例 #5
0
  TimerEventHandle TimerQueue::add( TimerFunc f, void* functionArgs, uint32_t milliseconds, su_time_t now ) {
    //self check
    assert( m_length == numberOfElements()) ;
    assert( 0 != m_length || (NULL == m_head && NULL == m_tail) ) ;
    assert( 1 != m_length || (m_head == m_tail)) ;
    assert( m_length < 2 || (m_head != m_tail)) ;
    assert( !(NULL == m_head && NULL != m_tail)) ;
    assert( !(NULL == m_tail && NULL != m_head)) ;

    su_time_t when = su_time_add(now, milliseconds) ;
    queueEntry_t* entry = new queueEntry_t(this, f, functionArgs, when) ;
    TimerEventHandle handle = entry ;
    assert(handle) ;
    int queueLength ;

    if( entry ) {
#ifndef TEST
      DR_LOG(log_debug) << m_name << ": Adding entry to go off in " << std::dec << milliseconds << "ms" ;
#endif
      //std::cout << "Adding entry to go off in " << milliseconds << "ms" << std::endl;

      if( NULL == m_head ) {
        assert( NULL == m_tail ) ;
        m_head = m_tail = entry; 
#ifndef TEST
        DR_LOG(log_debug) << m_name << ": Adding entry to the head (queue was empty), length: " << dec << m_length+1 ;
#endif
        //std::cout << "Adding entry to the head of the queue (it was empty)" << std::endl ;
      }
      else if( NULL != m_tail && su_time_cmp( when, m_tail->m_when ) > 0) {
        //one class of timer queues will always be appending entries, so check the tail
        //before starting to iterate through
#ifndef TEST
          DR_LOG(log_debug) << m_name << ": Adding entry to the tail of the queue: length " << dec << m_length+1;
#endif
          //std::cout << "Adding entry to the tail of the queue" << std::endl ;
          entry->m_prev = m_tail ;
          m_tail->m_next = entry ;
          m_tail = entry ;
      }
      else { 
        //iterate
        queueEntry_t* ptr = m_head ;
        int idx = 0 ;
        do {
          if( su_time_cmp( when, ptr->m_when ) < 0) {
#ifndef TEST
            DR_LOG(log_debug) << m_name << ": Adding entry at position " << std::dec << idx << " of the queue, length: " << dec << m_length+1 ;
#endif
            //std::cout << "Adding entry at position " << idx << " of the queue" << std::endl ;
            entry->m_next = ptr ;
            if( 0 == idx ) {
              m_head = entry ;
            }   
            else {
              entry->m_prev = ptr->m_prev ; 
              ptr->m_prev->m_next = entry ;

            }         
            ptr->m_prev = entry ;
            break ;
          }
          idx++ ;
        } while( NULL != (ptr = ptr->m_next) ) ;
        assert( NULL != ptr ) ;
/*
        if( NULL == ptr ) {
#ifndef TEST
          DR_LOG(log_debug) << m_name << ": Adding entry to the tail of the queue: length " << dec << m_length+1;
#endif
          //std::cout << "Adding entry to the tail of the queue" << std::endl ;
          entry->m_prev = m_tail ;
          m_tail->m_next = entry ;
          m_tail = entry ;
        }
*/
      }
      queueLength = ++m_length ;
    }
    else {
      //DR_LOG(log_error) << "Error allocating queue entry" ;
      //std::cerr << "Error allocating queue entry" << std::endl ;
      return NULL ;
    }

    //only need to set the timer if we added to the front
    if( m_head == entry ) {
      //DR_LOG(log_debug) << "timer add: Setting timer for " << milliseconds  << "ms" ;
      //std::cout << "timer add: Setting timer for " << milliseconds  << "ms" << std::endl;
      int rc = su_timer_set_at(m_timer, timer_function, this, when);
      assert( 0 == rc ) ;
    }

    //DR_LOG(log_debug) << "timer add: queue length is now " << queueLength ;
    //std::cout << "timer add: queue length is now " << queueLength << std::endl;

     //self check
    assert( m_length == numberOfElements()) ;
    assert( 0 != m_length || (NULL == m_head && NULL == m_tail) ) ;
    assert( 1 != m_length || (m_head == m_tail)) ;
    assert( m_length < 2 || (m_head != m_tail)) ;
    assert( !(NULL == m_head && NULL != m_tail)) ;
    assert( !(NULL == m_tail && NULL != m_head)) ;

    return handle ;

  }
コード例 #6
0
  void TimerQueue::doTimer(su_timer_t* timer) {
    //self check
    assert( m_length == numberOfElements()) ;
    assert( 0 != m_length || (NULL == m_head && NULL == m_tail) ) ;
    assert( 1 != m_length || (m_head == m_tail)) ;
    assert( m_length < 2 || (m_head != m_tail)) ;
    assert( !(NULL == m_head && NULL != m_tail)) ;
    assert( !(NULL == m_tail && NULL != m_head)) ;

#ifndef TEST
    DR_LOG(log_debug) << m_name << ": running timer function" ;
#endif
    //std::cout << "doTimer: running timer function with " << m_length << " timers queued " << std::endl;

    if( m_in_timer ) return ;
    m_in_timer = 1 ;

    queueEntry_t* expired = NULL ;
    queueEntry_t* tailExpired = NULL ;

    su_time_t now = su_now() ;
    assert( NULL != m_head ) ;

    queueEntry_t* ptr = m_head ;
    while( ptr && su_time_cmp( ptr->m_when, now ) < 0 ) {
      //std::cout << "expiring a timer" << std::endl ;
      m_length-- ;
      m_head = ptr->m_next ;
      if( m_head ) m_head->m_prev = NULL ;
      else m_tail = NULL ;

      //detach and assemble them into a new queue temporarily
      if( !expired ) {
        expired = tailExpired = ptr ;
        ptr->m_prev = ptr->m_next = NULL ;
      }
      else {
        tailExpired->m_next = ptr ;
        ptr->m_prev = tailExpired ;
        tailExpired = ptr ;
      }
      ptr = ptr->m_next ;
    }

    if( NULL == m_head ) {
#ifndef TEST
      DR_LOG(log_debug) << m_name << ": timer not set (queue is empty after processing expired timers), length: " << dec << m_length ;
#endif
      //std::cout << "doTimer: timer not set (queue is empty after processing expired timers)" << std::endl;
      assert( 0 == m_length ) ;
    }
    else {
      //std::cout << "doTimer: Setting timer for " << su_duration( m_head->m_when, su_now() )  << "ms after processing expired timers" << std::endl;
#ifndef TEST
      DR_LOG(log_debug) << m_name << ": Setting timer for " << su_duration( m_head->m_when, su_now() )  << 
        "ms after processing expired timers, length: "  << dec << m_length ;
#endif
      int rc = su_timer_set_at(m_timer, timer_function, this, m_head->m_when);      
    }
    m_in_timer = 0 ;

    while( NULL != expired ) {
      expired->m_function( expired->m_functionArgs ) ;
      queueEntry_t* p = expired ;
      expired = expired->m_next ;
      delete p ;
    }    

    //self check
    assert( m_length == numberOfElements()) ;
    assert( 0 != m_length || (NULL == m_head && NULL == m_tail) ) ;
    assert( 1 != m_length || (m_head == m_tail)) ;
    assert( m_length < 2 || (m_head != m_tail)) ;
    assert( !(NULL == m_head && NULL != m_tail)) ;
    assert( !(NULL == m_tail && NULL != m_head)) ;
  }