Merge remote branch 'github/20_http_read_after_write'

This commit is contained in:
Nick Mathewson 2010-10-26 21:33:22 -04:00
commit 84a7053e41
2 changed files with 31 additions and 0 deletions

View File

@ -12,6 +12,7 @@
#include "event2/event_struct.h"
#include "util-internal.h"
#include "defer-internal.h"
#define HTTP_CONNECT_TIMEOUT 45
#define HTTP_WRITE_TIMEOUT 50
@ -96,6 +97,8 @@ struct evhttp_connection {
void (*closecb)(struct evhttp_connection *, void *);
void *closecb_arg;
struct deferred_cb read_more_deferred_cb;
struct event_base *base;
struct evdns_base *dns_base;
};

28
http.c
View File

@ -919,6 +919,9 @@ evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
bufferevent_enable(evcon->bufev, EV_READ);
}
#define get_deferred_queue(evcon) \
(event_base_get_deferred_cb_queue((evcon)->base))
/*
* Gets called when more data becomes available
*/
@ -929,6 +932,10 @@ evhttp_read_cb(struct bufferevent *bufev, void *arg)
struct evhttp_connection *evcon = arg;
struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
/* Cancel if it's pending. */
event_deferred_cb_cancel(get_deferred_queue(evcon),
&evcon->read_more_deferred_cb);
switch (evcon->state) {
case EVCON_READING_FIRSTLINE:
evhttp_read_firstline(evcon, req);
@ -958,6 +965,13 @@ evhttp_read_cb(struct bufferevent *bufev, void *arg)
}
}
static void
evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
{
struct evhttp_connection *evcon = data;
evhttp_read_cb(evcon->bufev, evcon);
}
static void
evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
{
@ -1011,6 +1025,9 @@ evhttp_connection_free(struct evhttp_connection *evcon)
if (evcon->bufev != NULL)
bufferevent_free(evcon->bufev);
event_deferred_cb_cancel(get_deferred_queue(evcon),
&evcon->read_more_deferred_cb);
if (evcon->fd != -1) {
shutdown(evcon->fd, EVUTIL_SHUT_WR);
evutil_closesocket(evcon->fd);
@ -1844,6 +1861,10 @@ evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
bufferevent_base_set(base, evcon->bufev);
}
event_deferred_cb_init(&evcon->read_more_deferred_cb,
evhttp_deferred_read_cb, evcon);
evcon->dns_base = dnsbase;
return (evcon);
@ -2036,6 +2057,13 @@ evhttp_start_read(struct evhttp_connection *evcon)
bufferevent_disable(evcon->bufev, EV_WRITE);
bufferevent_enable(evcon->bufev, EV_READ);
evcon->state = EVCON_READING_FIRSTLINE;
/* If there's still data pending, process it next time through the
* loop. Don't do it now; that could get recusive. */
if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
event_deferred_cb_schedule(get_deferred_queue(evcon),
&evcon->read_more_deferred_cb);
}
}
static void