mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
Merge branch 'http-fix-fd-leak'
* http-fix-fd-leak: http: fix fd leak on fd reset (by using bufferevent_replacefd()) bufferevent: introduce bufferevent_replacefd() (like setfd() but also close fd) Fixes: #1143
This commit is contained in:
commit
3b9b655da9
@ -881,6 +881,34 @@ bufferevent_setfd(struct bufferevent *bev, evutil_socket_t fd)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bufferevent_replacefd(struct bufferevent *bev, evutil_socket_t fd)
|
||||||
|
{
|
||||||
|
union bufferevent_ctrl_data d;
|
||||||
|
int err = -1;
|
||||||
|
evutil_socket_t old_fd = EVUTIL_INVALID_SOCKET;
|
||||||
|
|
||||||
|
BEV_LOCK(bev);
|
||||||
|
if (bev->be_ops->ctrl) {
|
||||||
|
err = bev->be_ops->ctrl(bev, BEV_CTRL_GET_FD, &d);
|
||||||
|
if (!err) {
|
||||||
|
old_fd = d.fd;
|
||||||
|
if (old_fd != EVUTIL_INVALID_SOCKET) {
|
||||||
|
err = evutil_closesocket(old_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!err) {
|
||||||
|
d.fd = fd;
|
||||||
|
err = bev->be_ops->ctrl(bev, BEV_CTRL_SET_FD, &d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
event_debug(("%s: cannot replace fd for %p from "EV_SOCK_FMT" to "EV_SOCK_FMT, __func__, bev, old_fd, fd));
|
||||||
|
BEV_UNLOCK(bev);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
evutil_socket_t
|
evutil_socket_t
|
||||||
bufferevent_getfd(struct bufferevent *bev)
|
bufferevent_getfd(struct bufferevent *bev)
|
||||||
{
|
{
|
||||||
|
8
http.c
8
http.c
@ -1420,7 +1420,7 @@ evhttp_connection_reset_hard_(struct evhttp_connection *evcon)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* XXXX This is not actually an optimal fix. Instead we ought to have
|
/* XXXX This is not actually an optimal fix. Instead we ought to have
|
||||||
an API for "stop connecting", or use bufferevent_setfd to turn off
|
an API for "stop connecting", or use bufferevent_replacefd to turn off
|
||||||
connecting. But for Libevent 2.0, this seems like a minimal change
|
connecting. But for Libevent 2.0, this seems like a minimal change
|
||||||
least likely to disrupt the rest of the bufferevent and http code.
|
least likely to disrupt the rest of the bufferevent and http code.
|
||||||
|
|
||||||
@ -1437,7 +1437,7 @@ evhttp_connection_reset_hard_(struct evhttp_connection *evcon)
|
|||||||
(*evcon->closecb)(evcon, evcon->closecb_arg);
|
(*evcon->closecb)(evcon, evcon->closecb_arg);
|
||||||
|
|
||||||
/** FIXME: manipulating with fd is unwanted */
|
/** FIXME: manipulating with fd is unwanted */
|
||||||
err = bufferevent_setfd(evcon->bufev, -1);
|
err = bufferevent_replacefd(evcon->bufev, -1);
|
||||||
EVUTIL_ASSERT(!err && "setfd");
|
EVUTIL_ASSERT(!err && "setfd");
|
||||||
|
|
||||||
/* we need to clean up any buffered data */
|
/* we need to clean up any buffered data */
|
||||||
@ -2766,7 +2766,7 @@ evhttp_connection_connect_(struct evhttp_connection *evcon)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufferevent_setfd(evcon->bufev, fd))
|
if (bufferevent_replacefd(evcon->bufev, fd))
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4495,7 +4495,7 @@ evhttp_get_request_connection(
|
|||||||
evcon->flags |= EVHTTP_CON_INCOMING;
|
evcon->flags |= EVHTTP_CON_INCOMING;
|
||||||
evcon->state = EVCON_READING_FIRSTLINE;
|
evcon->state = EVCON_READING_FIRSTLINE;
|
||||||
|
|
||||||
if (bufferevent_setfd(evcon->bufev, fd))
|
if (bufferevent_replacefd(evcon->bufev, fd))
|
||||||
goto err;
|
goto err;
|
||||||
if (bufferevent_enable(evcon->bufev, EV_READ))
|
if (bufferevent_enable(evcon->bufev, EV_READ))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -377,6 +377,18 @@ void bufferevent_getcb(struct bufferevent *bufev,
|
|||||||
EVENT2_EXPORT_SYMBOL
|
EVENT2_EXPORT_SYMBOL
|
||||||
int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);
|
int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Replaces the file descriptor on which the bufferevent operates.
|
||||||
|
Not supported for all bufferevent types.
|
||||||
|
|
||||||
|
Unlike bufferevent_setfd() it will close previous file descriptor (if any).
|
||||||
|
|
||||||
|
@param bufev the bufferevent object for which to change the file descriptor
|
||||||
|
@param fd the file descriptor to operate on
|
||||||
|
*/
|
||||||
|
EVENT2_EXPORT_SYMBOL
|
||||||
|
int bufferevent_replacefd(struct bufferevent *bufev, evutil_socket_t fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the file descriptor associated with a bufferevent, or -1 if
|
Returns the file descriptor associated with a bufferevent, or -1 if
|
||||||
no file descriptor is associated with the bufferevent.
|
no file descriptor is associated with the bufferevent.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user