From 0848814ac496167133bec5f8d564387b5111440f Mon Sep 17 00:00:00 2001 From: Kevin Ko Date: Fri, 20 May 2011 23:23:44 -0400 Subject: [PATCH] Fix failing assertion introducd in commit 0d6622e Patch in question: - Fix the case when failed evhttp_make_request() leaved request in the queue. - http://levent.git.sourceforge.net/git/gitweb.cgi?p=levent/libevent;a=commit;h=0d6622e The above patch introduces a failing assertion in evhttp_connection_fail(). This happens because the patch defers the assignment of the outstanding request to the evcon->requests list, while evhttp_connection_fail() assumes that the request lies in the list. One scenario in which this can happen is when the request list is empty and a connection is made to an unreachable host. The assertion will then fail after bufferevent_socket_connect() errors out (with ENETUNREACH in my case). --- http.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/http.c b/http.c index 06fe6148..c878a571 100644 --- a/http.c +++ b/http.c @@ -2194,21 +2194,21 @@ evhttp_make_request(struct evhttp_connection *evcon, req->evcon = evcon; EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION)); + TAILQ_INSERT_TAIL(&evcon->requests, req, next); + /* If the connection object is not connected; make it so */ if (!evhttp_connected(evcon)) { int res = evhttp_connection_connect(evcon); - /* - * Enqueue the request only if we aren't going to - * return failure from evhttp_make_request(). - */ - if (res == 0) - TAILQ_INSERT_TAIL(&evcon->requests, req, next); + /* evhttp_connection_fail(), which is called through + * evhttp_connection_connect(), assumes that req lies in + * evcon->requests. Thus, enqueue the request in advance and r + * it in the error case. */ + if (res != 0) + TAILQ_REMOVE(&evcon->requests, req, next); return res; } - TAILQ_INSERT_TAIL(&evcon->requests, req, next); - /* * If it's connected already and we are the first in the queue, * then we can dispatch this request immediately. Otherwise, it