mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-18 16:54:42 -04:00
Merge remote branch 'github/http_and_listener'
This commit is contained in:
commit
9c71a3413a
38
http.c
38
http.c
@ -2764,23 +2764,35 @@ evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
|
|||||||
const int flags =
|
const int flags =
|
||||||
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
|
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
|
||||||
|
|
||||||
|
listener = evconnlistener_new(http->base, NULL, NULL,
|
||||||
|
flags,
|
||||||
|
0, /* Backlog is '0' because we already said 'listen' */
|
||||||
|
fd);
|
||||||
|
if (!listener)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
bound = evhttp_bind_listener(http, listener);
|
||||||
|
if (!bound) {
|
||||||
|
evconnlistener_free(listener);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct evhttp_bound_socket *
|
||||||
|
evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
|
||||||
|
{
|
||||||
|
struct evhttp_bound_socket *bound;
|
||||||
|
|
||||||
bound = mm_malloc(sizeof(struct evhttp_bound_socket));
|
bound = mm_malloc(sizeof(struct evhttp_bound_socket));
|
||||||
if (bound == NULL)
|
if (bound == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
listener = evconnlistener_new(http->base, accept_socket_cb, http,
|
|
||||||
flags,
|
|
||||||
0, /* Backlog is '0' because we already said 'listen' */
|
|
||||||
fd);
|
|
||||||
if (!listener) {
|
|
||||||
mm_free(bound);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
bound->listener = listener;
|
bound->listener = listener;
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&http->sockets, bound, next);
|
TAILQ_INSERT_TAIL(&http->sockets, bound, next);
|
||||||
|
|
||||||
return (bound);
|
evconnlistener_set_cb(listener, accept_socket_cb, http);
|
||||||
|
return bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
evutil_socket_t evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
|
evutil_socket_t evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
|
||||||
@ -2788,6 +2800,12 @@ evutil_socket_t evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
|
|||||||
return evconnlistener_get_fd(bound->listener);
|
return evconnlistener_get_fd(bound->listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct evconnlistener *
|
||||||
|
evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
|
||||||
|
{
|
||||||
|
return bound->listener;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
|
evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,7 @@ struct evhttp;
|
|||||||
struct evhttp_request;
|
struct evhttp_request;
|
||||||
struct evkeyvalq;
|
struct evkeyvalq;
|
||||||
struct evhttp_bound_socket;
|
struct evhttp_bound_socket;
|
||||||
|
struct evconnlistener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new HTTP server.
|
* Create a new HTTP server.
|
||||||
@ -130,6 +131,18 @@ int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd);
|
|||||||
*/
|
*/
|
||||||
struct evhttp_bound_socket *evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd);
|
struct evhttp_bound_socket *evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The most low-level evhttp_bind/accept method: takes an evconnlistener, and
|
||||||
|
* returns an evhttp_bound_socket. The listener will be freed when the bound
|
||||||
|
* socket is freed.
|
||||||
|
*/
|
||||||
|
struct evhttp_bound_socket *evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the listener used to implement a bound socket.
|
||||||
|
*/
|
||||||
|
struct evconnlistener *evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes an HTTP server stop accepting connections on the specified socket
|
* Makes an HTTP server stop accepting connections on the specified socket
|
||||||
*
|
*
|
||||||
|
@ -75,7 +75,9 @@ typedef void (*evconnlistener_errorcb)(struct evconnlistener *, void *);
|
|||||||
on a given file descriptor.
|
on a given file descriptor.
|
||||||
|
|
||||||
@param base The event base to associate the listener with.
|
@param base The event base to associate the listener with.
|
||||||
@param cb A callback to be invoked when a new connection arrives.
|
@param cb A callback to be invoked when a new connection arrives. If the
|
||||||
|
callback is NULL, the listener will be treated as disabled until the
|
||||||
|
callback is set.
|
||||||
@param ptr A user-supplied pointer to give to the callback.
|
@param ptr A user-supplied pointer to give to the callback.
|
||||||
@param flags Any number of LEV_OPT_* flags
|
@param flags Any number of LEV_OPT_* flags
|
||||||
@param backlog Passed to the listen() call to determine the length of the
|
@param backlog Passed to the listen() call to determine the length of the
|
||||||
@ -93,7 +95,9 @@ struct evconnlistener *evconnlistener_new(struct event_base *base,
|
|||||||
on a given address.
|
on a given address.
|
||||||
|
|
||||||
@param base The event base to associate the listener with.
|
@param base The event base to associate the listener with.
|
||||||
@param cb A callback to be invoked when a new connection arrives.
|
@param cb A callback to be invoked when a new connection arrives. If the
|
||||||
|
callback is NULL, the listener will be treated as disabled until the
|
||||||
|
callback is set.
|
||||||
@param ptr A user-supplied pointer to give to the callback.
|
@param ptr A user-supplied pointer to give to the callback.
|
||||||
@param flags Any number of LEV_OPT_* flags
|
@param flags Any number of LEV_OPT_* flags
|
||||||
@param backlog Passed to the listen() call to determine the length of the
|
@param backlog Passed to the listen() call to determine the length of the
|
||||||
@ -123,6 +127,11 @@ struct event_base *evconnlistener_get_base(struct evconnlistener *lev);
|
|||||||
/** Return the socket that an evconnlistner is listening on. */
|
/** Return the socket that an evconnlistner is listening on. */
|
||||||
evutil_socket_t evconnlistener_get_fd(struct evconnlistener *lev);
|
evutil_socket_t evconnlistener_get_fd(struct evconnlistener *lev);
|
||||||
|
|
||||||
|
/** Change the callback on the listener to cb and its user_data to arg.
|
||||||
|
*/
|
||||||
|
void evconnlistener_set_cb(struct evconnlistener *lev,
|
||||||
|
evconnlistener_cb cb, void *arg);
|
||||||
|
|
||||||
/** Set an evconnlistener's error callback. */
|
/** Set an evconnlistener's error callback. */
|
||||||
void evconnlistener_set_error_cb(struct evconnlistener *lev,
|
void evconnlistener_set_error_cb(struct evconnlistener *lev,
|
||||||
evconnlistener_errorcb errorcb);
|
evconnlistener_errorcb errorcb);
|
||||||
|
41
listener.c
41
listener.c
@ -73,7 +73,8 @@ struct evconnlistener {
|
|||||||
evconnlistener_errorcb errorcb;
|
evconnlistener_errorcb errorcb;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
int refcnt;
|
short refcnt;
|
||||||
|
unsigned enabled : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct evconnlistener_event {
|
struct evconnlistener_event {
|
||||||
@ -89,7 +90,6 @@ struct evconnlistener_iocp {
|
|||||||
struct event_iocp_port *port;
|
struct event_iocp_port *port;
|
||||||
short n_accepting;
|
short n_accepting;
|
||||||
unsigned shutting_down : 1;
|
unsigned shutting_down : 1;
|
||||||
unsigned enabled : 1;
|
|
||||||
struct accepting_socket **accepting;
|
struct accepting_socket **accepting;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -185,6 +185,7 @@ evconnlistener_new(struct event_base *base,
|
|||||||
|
|
||||||
event_assign(&lev->listener, base, fd, EV_READ|EV_PERSIST,
|
event_assign(&lev->listener, base, fd, EV_READ|EV_PERSIST,
|
||||||
listener_read_cb, lev);
|
listener_read_cb, lev);
|
||||||
|
|
||||||
evconnlistener_enable(&lev->base);
|
evconnlistener_enable(&lev->base);
|
||||||
|
|
||||||
return &lev->base;
|
return &lev->base;
|
||||||
@ -268,7 +269,11 @@ evconnlistener_enable(struct evconnlistener *lev)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
LOCK(lev);
|
LOCK(lev);
|
||||||
r = lev->ops->enable(lev);
|
lev->enabled = 1;
|
||||||
|
if (lev->cb)
|
||||||
|
r = lev->ops->enable(lev);
|
||||||
|
else
|
||||||
|
r = 0;
|
||||||
UNLOCK(lev);
|
UNLOCK(lev);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -278,6 +283,7 @@ evconnlistener_disable(struct evconnlistener *lev)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
LOCK(lev);
|
LOCK(lev);
|
||||||
|
lev->enabled = 0;
|
||||||
r = lev->ops->disable(lev);
|
r = lev->ops->disable(lev);
|
||||||
UNLOCK(lev);
|
UNLOCK(lev);
|
||||||
return r;
|
return r;
|
||||||
@ -335,7 +341,23 @@ event_listener_getbase(struct evconnlistener *lev)
|
|||||||
return event_get_base(&lev_e->listener);
|
return event_get_base(&lev_e->listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void evconnlistener_set_error_cb(struct evconnlistener *lev,
|
void
|
||||||
|
evconnlistener_set_cb(struct evconnlistener *lev,
|
||||||
|
evconnlistener_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
int enable = 0;
|
||||||
|
LOCK(lev);
|
||||||
|
if (lev->enabled && !lev->cb)
|
||||||
|
enable = 1;
|
||||||
|
lev->cb = cb;
|
||||||
|
lev->user_data = arg;
|
||||||
|
if (enable)
|
||||||
|
evconnlistener_enable(lev);
|
||||||
|
UNLOCK(lev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evconnlistener_set_error_cb(struct evconnlistener *lev,
|
||||||
evconnlistener_errorcb errorcb)
|
evconnlistener_errorcb errorcb)
|
||||||
{
|
{
|
||||||
LOCK(lev);
|
LOCK(lev);
|
||||||
@ -474,7 +496,7 @@ start_accepting(struct accepting_socket *as)
|
|||||||
SOCKET s = socket(as->family, SOCK_STREAM, 0);
|
SOCKET s = socket(as->family, SOCK_STREAM, 0);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (!as->lev->enabled)
|
if (!as->lev->base.enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (s == INVALID_SOCKET) {
|
if (s == INVALID_SOCKET) {
|
||||||
@ -574,7 +596,7 @@ accepted_socket_invoke_user_cb(struct deferred_cb *dcb, void *arg)
|
|||||||
if (errorcb) {
|
if (errorcb) {
|
||||||
WSASetLastError(error);
|
WSASetLastError(error);
|
||||||
errorcb(lev, data);
|
errorcb(lev, data);
|
||||||
} else {
|
} else if (cb) {
|
||||||
cb(lev, sock, sa_remote, socklen_remote, data);
|
cb(lev, sock, sa_remote, socklen_remote, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +660,6 @@ iocp_listener_enable(struct evconnlistener *lev)
|
|||||||
EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
|
EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
|
||||||
|
|
||||||
LOCK(lev);
|
LOCK(lev);
|
||||||
lev_iocp->enabled = 1;
|
|
||||||
for (i = 0; i < lev_iocp->n_accepting; ++i) {
|
for (i = 0; i < lev_iocp->n_accepting; ++i) {
|
||||||
struct accepting_socket *as = lev_iocp->accepting[i];
|
struct accepting_socket *as = lev_iocp->accepting[i];
|
||||||
if (!as)
|
if (!as)
|
||||||
@ -660,7 +681,6 @@ iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown)
|
|||||||
EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
|
EVUTIL_UPCAST(lev, struct evconnlistener_iocp, base);
|
||||||
|
|
||||||
LOCK(lev);
|
LOCK(lev);
|
||||||
lev_iocp->enabled = 0;
|
|
||||||
for (i = 0; i < lev_iocp->n_accepting; ++i) {
|
for (i = 0; i < lev_iocp->n_accepting; ++i) {
|
||||||
struct accepting_socket *as = lev_iocp->accepting[i];
|
struct accepting_socket *as = lev_iocp->accepting[i];
|
||||||
if (!as)
|
if (!as)
|
||||||
@ -760,11 +780,12 @@ evconnlistener_new_async(struct event_base *base,
|
|||||||
lev->base.user_data = ptr;
|
lev->base.user_data = ptr;
|
||||||
lev->base.flags = flags;
|
lev->base.flags = flags;
|
||||||
lev->base.refcnt = 1;
|
lev->base.refcnt = 1;
|
||||||
|
lev->base.enabled = 1;
|
||||||
|
|
||||||
lev->port = event_base_get_iocp(base);
|
lev->port = event_base_get_iocp(base);
|
||||||
lev->fd = fd;
|
lev->fd = fd;
|
||||||
lev->event_base = base;
|
lev->event_base = base;
|
||||||
lev->enabled = 1;
|
|
||||||
|
|
||||||
if (event_iocp_port_associate(lev->port, fd, 1) < 0)
|
if (event_iocp_port_associate(lev->port, fd, 1) < 0)
|
||||||
goto err_free_lev;
|
goto err_free_lev;
|
||||||
@ -784,7 +805,7 @@ evconnlistener_new_async(struct event_base *base,
|
|||||||
event_warnx("Couldn't create accepting socket");
|
event_warnx("Couldn't create accepting socket");
|
||||||
goto err_free_accepting;
|
goto err_free_accepting;
|
||||||
}
|
}
|
||||||
if (start_accepting(lev->accepting[i]) < 0) {
|
if (cb && start_accepting(lev->accepting[i]) < 0) {
|
||||||
event_warnx("Couldn't start accepting on socket");
|
event_warnx("Couldn't start accepting on socket");
|
||||||
EnterCriticalSection(&lev->accepting[i]->lock);
|
EnterCriticalSection(&lev->accepting[i]->lock);
|
||||||
free_and_unlock_accepting_socket(lev->accepting[i]);
|
free_and_unlock_accepting_socket(lev->accepting[i]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user