mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-19 09:15:34 -04:00
allow gotsig to terminate active event loop;
free http connection on failed incoming connections; bugs pointed out by Dug Song. svn:r293
This commit is contained in:
parent
ec0679199f
commit
c6e285d31a
2
event.c
2
event.c
@ -311,6 +311,8 @@ event_process_active(struct event_base *base)
|
||||
ncalls--;
|
||||
ev->ev_ncalls = ncalls;
|
||||
(*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
if (event_gotsig)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
http.c
50
http.c
@ -426,10 +426,10 @@ evhttp_connection_incoming_fail(struct evhttp_request *req,
|
||||
case EVCON_HTTP_TIMEOUT:
|
||||
case EVCON_HTTP_EOF:
|
||||
/*
|
||||
* these are cases in which we probably should just close
|
||||
* the connection and actually send a reply. this case may
|
||||
* happen when a browser keeps a persistent connection open
|
||||
* and we timeout on the read.
|
||||
* these are cases in which we probably should just
|
||||
* close the connection and not send a reply. this
|
||||
* case may happen when a browser keeps a persistent
|
||||
* connection open and we timeout on the read.
|
||||
*/
|
||||
return (-1);
|
||||
case EVCON_HTTP_INVALID_HEADER:
|
||||
@ -439,6 +439,11 @@ evhttp_connection_incoming_fail(struct evhttp_request *req,
|
||||
free(req->uri);
|
||||
req->uri = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* the callback needs to send a reply, once the reply has
|
||||
* been send, the connection should get freed.
|
||||
*/
|
||||
(*req->cb)(req, req->cb_arg);
|
||||
}
|
||||
|
||||
@ -452,28 +457,31 @@ evhttp_connection_fail(struct evhttp_connection *evcon,
|
||||
struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
|
||||
assert(req != NULL);
|
||||
|
||||
if (req->cb != NULL) {
|
||||
if (evcon->flags & EVHTTP_CON_INCOMING) {
|
||||
/*
|
||||
* we are passing the request object if we have an incoming
|
||||
* request that somehow needs to be answered. we need to
|
||||
* wait for the answer to travel over the wire before we can
|
||||
* kill the connection.
|
||||
* for incoming requests, there are two different
|
||||
* failure cases. it's either a network level error
|
||||
* or an http layer error. for problems on the network
|
||||
* layer like timeouts we just drop the connections.
|
||||
* For HTTP problems, we might have to send back a
|
||||
* reply before the connection can be freed.
|
||||
*/
|
||||
if (evcon->flags & EVHTTP_CON_INCOMING) {
|
||||
if (evhttp_connection_incoming_fail(req, error) == 0)
|
||||
return;
|
||||
} else {
|
||||
(*req->cb)(NULL, req->cb_arg);
|
||||
}
|
||||
if (evhttp_connection_incoming_fail(req, error) == -1)
|
||||
evhttp_connection_free(evcon);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset the connection */
|
||||
evhttp_connection_reset(evcon);
|
||||
|
||||
if (req->cb != NULL)
|
||||
(*req->cb)(NULL, req->cb_arg);
|
||||
|
||||
TAILQ_REMOVE(&evcon->requests, req, next);
|
||||
evhttp_request_free(req);
|
||||
|
||||
/* xxx: maybe we should fail all requests??? */
|
||||
|
||||
/* reset the connection */
|
||||
evhttp_connection_reset(evcon);
|
||||
|
||||
/* We are trying the next request that was queued on us */
|
||||
if (TAILQ_FIRST(&evcon->requests) != NULL)
|
||||
@ -626,6 +634,14 @@ evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
|
||||
void
|
||||
evhttp_connection_free(struct evhttp_connection *evcon)
|
||||
{
|
||||
struct evhttp_request *req;
|
||||
|
||||
/* remove all requests that might be queued on this connection */
|
||||
while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
|
||||
TAILQ_REMOVE(&evcon->requests, req, next);
|
||||
evhttp_request_free(req);
|
||||
}
|
||||
|
||||
if (evcon->http_server != NULL) {
|
||||
struct evhttp *http = evcon->http_server;
|
||||
TAILQ_REMOVE(&http->connections, evcon, next);
|
||||
|
Loading…
x
Reference in New Issue
Block a user