mirror of
https://github.com/cuberite/libevent.git
synced 2025-08-04 01:36:23 -04:00
Correctly terminate IO on an async bufferevent on bufferevent_free
This commit is contained in:
parent
0ff2c5a922
commit
e6af35d762
@ -197,7 +197,8 @@ struct bufferevent_private {
|
|||||||
enum bufferevent_ctrl_op {
|
enum bufferevent_ctrl_op {
|
||||||
BEV_CTRL_SET_FD,
|
BEV_CTRL_SET_FD,
|
||||||
BEV_CTRL_GET_FD,
|
BEV_CTRL_GET_FD,
|
||||||
BEV_CTRL_GET_UNDERLYING
|
BEV_CTRL_GET_UNDERLYING,
|
||||||
|
BEV_CTRL_CANCEL_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Possible data types for a control callback */
|
/** Possible data types for a control callback */
|
||||||
|
@ -59,6 +59,9 @@
|
|||||||
#include "evbuffer-internal.h"
|
#include "evbuffer-internal.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
|
||||||
|
static void _bufferevent_cancel_all(struct bufferevent *bev);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
|
||||||
{
|
{
|
||||||
@ -674,6 +677,7 @@ bufferevent_free(struct bufferevent *bufev)
|
|||||||
{
|
{
|
||||||
BEV_LOCK(bufev);
|
BEV_LOCK(bufev);
|
||||||
bufferevent_setcb(bufev, NULL, NULL, NULL, NULL);
|
bufferevent_setcb(bufev, NULL, NULL, NULL, NULL);
|
||||||
|
_bufferevent_cancel_all(bufev);
|
||||||
_bufferevent_decref_and_unlock(bufev);
|
_bufferevent_decref_and_unlock(bufev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,6 +754,17 @@ bufferevent_getfd(struct bufferevent *bev)
|
|||||||
return (res<0) ? -1 : d.fd;
|
return (res<0) ? -1 : d.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bufferevent_cancel_all(struct bufferevent *bev)
|
||||||
|
{
|
||||||
|
union bufferevent_ctrl_data d;
|
||||||
|
memset(&d, 0, sizeof(d));
|
||||||
|
BEV_LOCK(bev);
|
||||||
|
if (bev->be_ops->ctrl)
|
||||||
|
bev->be_ops->ctrl(bev, BEV_CTRL_CANCEL_ALL, &d);
|
||||||
|
BEV_UNLOCK(bev);
|
||||||
|
}
|
||||||
|
|
||||||
short
|
short
|
||||||
bufferevent_get_enabled(struct bufferevent *bufev)
|
bufferevent_get_enabled(struct bufferevent *bufev)
|
||||||
{
|
{
|
||||||
|
@ -268,8 +268,8 @@ bev_async_consider_reading(struct bufferevent_async *beva)
|
|||||||
bufferevent_incref(bev);
|
bufferevent_incref(bev);
|
||||||
if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) {
|
if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) {
|
||||||
beva->ok = 0;
|
beva->ok = 0;
|
||||||
bufferevent_decref(bev);
|
|
||||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||||
|
bufferevent_decref(bev);
|
||||||
} else {
|
} else {
|
||||||
beva->read_in_progress = at_most;
|
beva->read_in_progress = at_most;
|
||||||
_bufferevent_decrement_read_buckets(&beva->bev, at_most);
|
_bufferevent_decrement_read_buckets(&beva->bev, at_most);
|
||||||
@ -379,8 +379,10 @@ be_async_destruct(struct bufferevent *bev)
|
|||||||
bev_async_del_write(bev_async);
|
bev_async_del_write(bev_async);
|
||||||
|
|
||||||
fd = _evbuffer_overlapped_get_fd(bev->input);
|
fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||||
if (bev_p->options & BEV_OPT_CLOSE_ON_FREE)
|
if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) {
|
||||||
|
/* XXXX possible double-close */
|
||||||
evutil_closesocket(fd);
|
evutil_closesocket(fd);
|
||||||
|
}
|
||||||
/* delete this in case non-blocking connect was used */
|
/* delete this in case non-blocking connect was used */
|
||||||
if (event_initialized(&bev->ev_write)) {
|
if (event_initialized(&bev->ev_write)) {
|
||||||
event_del(&bev->ev_write);
|
event_del(&bev->ev_write);
|
||||||
@ -669,8 +671,20 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
|
|||||||
_evbuffer_overlapped_set_fd(bev->output, data->fd);
|
_evbuffer_overlapped_set_fd(bev->output, data->fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case BEV_CTRL_CANCEL_ALL: {
|
||||||
|
struct bufferevent_async *bev_a = upcast(bev);
|
||||||
|
evutil_socket_t fd = _evbuffer_overlapped_get_fd(bev->input);
|
||||||
|
if (fd != (evutil_socket_t)INVALID_SOCKET &&
|
||||||
|
(bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) {
|
||||||
|
closesocket(fd);
|
||||||
|
}
|
||||||
|
bev_a->ok = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case BEV_CTRL_GET_UNDERLYING:
|
case BEV_CTRL_GET_UNDERLYING:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -504,6 +504,7 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
|
|||||||
return 0;
|
return 0;
|
||||||
case BEV_CTRL_GET_FD:
|
case BEV_CTRL_GET_FD:
|
||||||
case BEV_CTRL_SET_FD:
|
case BEV_CTRL_SET_FD:
|
||||||
|
case BEV_CTRL_CANCEL_ALL:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1167,6 +1167,7 @@ be_openssl_ctrl(struct bufferevent *bev,
|
|||||||
return -1;
|
return -1;
|
||||||
data->ptr = bev_ssl->underlying;
|
data->ptr = bev_ssl->underlying;
|
||||||
return 0;
|
return 0;
|
||||||
|
case BEV_CTRL_CANCEL_ALL:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -685,6 +685,7 @@ be_socket_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
|
|||||||
data->fd = event_get_fd(&bev->ev_read);
|
data->fd = event_get_fd(&bev->ev_read);
|
||||||
return 0;
|
return 0;
|
||||||
case BEV_CTRL_GET_UNDERLYING:
|
case BEV_CTRL_GET_UNDERLYING:
|
||||||
|
case BEV_CTRL_CANCEL_ALL:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user