/* these objects are kept in a circular list */
struct evdns_request *next, *prev;
+ u16 timeout_event_deleted; /**< Debugging: where was timeout_event
+ * deleted? 0 for "it's added." */
struct event timeout_event;
u16 trans_id; /* the transaction id */
struct event event;
/* these objects are kept in a circular list */
struct nameserver *next, *prev;
+ u16 timeout_event_deleted; /**< Debugging: where was timeout_event
+ * deleted? 0 for "it's added." */
struct event timeout_event; /* used to keep the timeout for */
/* when we next probe this server. */
/* Valid if state == 0 */
return 1;
}
+/* for debugging bug 929. XXXX021 */
+static int
+_add_timeout_event(u16 *lineno, struct event *ev, struct timeval *to)
+{
+ *lineno = 0;
+ return evtimer_add(ev, to);
+}
+#define add_timeout_event(s, to) \
+ (_add_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, (to)))
+
+/* for debugging bug 929. XXXX021 */
+static int
+_del_timeout_event(u16 *lineno, struct event *ev, int line)
+{
+ if (*lineno) {
+ log(EVDNS_LOG_WARN,
+ "Duplicate timeout event_del from line %d: first call "
+ "was at %d.", line, (int)*lineno);
+ return 0;
+ } else {
+ *lineno = (u16)line;
+ return event_del(ev);
+ }
+}
+#define del_timeout_event(s) \
+ (_del_timeout_event(&(s)->timeout_event_deleted, &(s)->timeout_event, \
+ __LINE__))
+
/* This walks the list of inflight requests to find the */
/* one with a matching transaction id. Returns NULL on */
/* failure */
static void
nameserver_probe_failed(struct nameserver *const ns) {
const struct timeval * timeout;
- (void) evtimer_del(&ns->timeout_event);
+ del_timeout_event(ns);
CLEAR(&ns->timeout_event);
if (ns->state == 1) {
/* This can happen if the nameserver acts in a way which makes us mark */
ns->failed_times++;
evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
- if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) {
+ if (add_timeout_event(ns, (struct timeval *) timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntop((struct sockaddr *)&ns->address));
ns->failed_times = 1;
evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
- if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
+ if (add_timeout_event(ns, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntop((struct sockaddr *)&ns->address));
if (ns->state) return;
log(EVDNS_LOG_WARN, "Nameserver %s is back up",
debug_ntop((struct sockaddr *)&ns->address));
- evtimer_del(&ns->timeout_event);
+ del_timeout_event(ns);
CLEAR(&ns->timeout_event);
ns->state = 1;
ns->failed_times = 0;
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
- evtimer_del(&req->timeout_event);
+ del_timeout_event(req);
CLEAR(&req->timeout_event);
search_request_finished(req);
nameserver_failed(req->ns, "request timed out.");
}
- (void) evtimer_del(&req->timeout_event);
+ del_timeout_event(req);
CLEAR(&req->timeout_event);
if (req->tx_count >= global_max_retransmits) {
/* this request has failed */
log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
- if (evtimer_add(&req->timeout_event, &global_timeout) < 0) {
+ if (add_timeout_event(req, &global_timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
(unsigned long) req);
struct nameserver *next = server->next;
(void) event_del(&server->event);
CLEAR(&server->event);
- (void) evtimer_del(&server->timeout_event);
+ del_timeout_event(server);
CLEAR(&server->timeout_event);
if (server->socket >= 0)
CLOSE_SOCKET(server->socket);
req->tx_count = req->reissue_count = 0;
req->ns = NULL;
/* ???? What to do about searches? */
- (void) evtimer_del(&req->timeout_event);
+ del_timeout_event(req);
CLEAR(&req->timeout_event);
req->trans_id = 0;
req->transmit_me = 0;
CLOSE_SOCKET(server->socket);
(void) event_del(&server->event);
if (server->state == 0)
- (void) event_del(&server->timeout_event);
+ del_timeout_event(server);
CLEAR(server);
mm_free(server);
if (server_next == server_head)