summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bufferevent-internal.h3
-rw-r--r--bufferevent.c15
-rw-r--r--bufferevent_async.c18
-rw-r--r--bufferevent_filter.c1
-rw-r--r--bufferevent_openssl.c1
-rw-r--r--bufferevent_sock.c1
6 files changed, 36 insertions, 3 deletions
diff --git a/bufferevent-internal.h b/bufferevent-internal.h
index dc471720..de1ff973 100644
--- a/bufferevent-internal.h
+++ b/bufferevent-internal.h
@@ -197,7 +197,8 @@ struct bufferevent_private {
enum bufferevent_ctrl_op {
BEV_CTRL_SET_FD,
BEV_CTRL_GET_FD,
- BEV_CTRL_GET_UNDERLYING
+ BEV_CTRL_GET_UNDERLYING,
+ BEV_CTRL_CANCEL_ALL
};
/** Possible data types for a control callback */
diff --git a/bufferevent.c b/bufferevent.c
index 9855d183..93a08015 100644
--- a/bufferevent.c
+++ b/bufferevent.c
@@ -59,6 +59,9 @@
#include "evbuffer-internal.h"
#include "util-internal.h"
+static void _bufferevent_cancel_all(struct bufferevent *bev);
+
+
void
bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
{
@@ -674,6 +677,7 @@ bufferevent_free(struct bufferevent *bufev)
{
BEV_LOCK(bufev);
bufferevent_setcb(bufev, NULL, NULL, NULL, NULL);
+ _bufferevent_cancel_all(bufev);
_bufferevent_decref_and_unlock(bufev);
}
@@ -750,6 +754,17 @@ bufferevent_getfd(struct bufferevent *bev)
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
bufferevent_get_enabled(struct bufferevent *bufev)
{
diff --git a/bufferevent_async.c b/bufferevent_async.c
index 9416e31f..a3b3ab1e 100644
--- a/bufferevent_async.c
+++ b/bufferevent_async.c
@@ -268,8 +268,8 @@ bev_async_consider_reading(struct bufferevent_async *beva)
bufferevent_incref(bev);
if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) {
beva->ok = 0;
- bufferevent_decref(bev);
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
+ bufferevent_decref(bev);
} else {
beva->read_in_progress = 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);
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);
+ }
/* delete this in case non-blocking connect was used */
if (event_initialized(&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);
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:
default:
return -1;
}
}
+
+
diff --git a/bufferevent_filter.c b/bufferevent_filter.c
index 7f19eb9a..234204fc 100644
--- a/bufferevent_filter.c
+++ b/bufferevent_filter.c
@@ -504,6 +504,7 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
return 0;
case BEV_CTRL_GET_FD:
case BEV_CTRL_SET_FD:
+ case BEV_CTRL_CANCEL_ALL:
default:
return -1;
}
diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
index c5d242ea..da50c600 100644
--- a/bufferevent_openssl.c
+++ b/bufferevent_openssl.c
@@ -1167,6 +1167,7 @@ be_openssl_ctrl(struct bufferevent *bev,
return -1;
data->ptr = bev_ssl->underlying;
return 0;
+ case BEV_CTRL_CANCEL_ALL:
default:
return -1;
}
diff --git a/bufferevent_sock.c b/bufferevent_sock.c
index 975b5b6c..089aedb4 100644
--- a/bufferevent_sock.c
+++ b/bufferevent_sock.c
@@ -685,6 +685,7 @@ be_socket_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
data->fd = event_get_fd(&bev->ev_read);
return 0;
case BEV_CTRL_GET_UNDERLYING:
+ case BEV_CTRL_CANCEL_ALL:
default:
return -1;
}