Hi guys,

My code is getting into an infinite loop while using the http client APIs with 
retries, when the server is unreachable.

The http client block is simple:

  http_conn_ = evhttp_connection_base_new(evq_, NULL, server_, http_port_);

  evhttp_connection_set_timeout(http_conn_, 3);
  evhttp_connection_set_retries(http_conn_, 3);

  evhttp_make_request(http_conn_, req, type, api);


The signature of the loop has been reported before (e.g. 
http://archives.seul.org/libevent/users/Mar-2012/msg00000.html), i.e. in this 
block:

  while ((ev = min_heap_top(&base->timeheap))) {
    if (evutil_timercmp(&ev->ev_timeout, &now, >))
      break;

    /* delete this event from the I/O queues */
    event_del_internal(ev);

    event_debug(("timeout_process: call %p",
                 ev->ev_callback));
    event_active_nolock(ev, EV_TIMEOUT, 1);
  }


with the 'ev' being the retry_ev with evhttp_connection_retry() callback.

Looking at http.c, the following snippet looked a bit suspicious:

static void
evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
{
  struct evcon_requestq requests;

  if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
    evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, 
evcon);
    /* XXXX handle failure from evhttp_add_event */
    evhttp_add_event(&evcon->retry_ev,
                     MIN(3600, 2 << evcon->retry_cnt),
                     HTTP_CONNECT_TIMEOUT);
    evcon->retry_cnt++;
    return;
  }
  <snip>
}

Before calling evtimer_assign() etc., shouldn't this be checking if retry_ev is 
added/active/pending?

Doing the same experiment without setting retries works fine, of course.

Any guidance on how to debug this?

Thanks,
- Pradosh
***********************************************************************
To unsubscribe, send an e-mail to [email protected] with
unsubscribe libevent-users    in the body.

Reply via email to