summaryrefslogtreecommitdiff
path: root/select.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-01-07 13:18:09 -0500
committerNick Mathewson <nickm@torproject.org>2011-01-07 13:18:09 -0500
commit83e805a41554a9e69ab7d2d75e56c30f3147ffa6 (patch)
tree873dc8f4e94bb15fb060abb7c1e6f3b6600e0d59 /select.c
parent3f8d22a123aef2698ce2e7d6ca1ad96d13760cef (diff)
downloadlibevent-83e805a41554a9e69ab7d2d75e56c30f3147ffa6.tar.gz
Handle resize failures in the select backend better.
Diffstat (limited to 'select.c')
-rw-r--r--select.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/select.c b/select.c
index 993a4e60..8327518e 100644
--- a/select.c
+++ b/select.c
@@ -100,7 +100,9 @@ select_init(struct event_base *base)
return (NULL);
if (select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask))) {
- mm_free(sop);
+ /* select_resize might have left this around. */
+ if (sop->event_readset_in)
+ mm_free(sop->event_readset_in);
return (NULL);
}
@@ -131,11 +133,14 @@ select_dispatch(struct event_base *base, struct timeval *tv)
size_t sz = sop->event_fdsz;
if (!(readset_out = mm_realloc(sop->event_readset_out, sz)))
return (-1);
+ sop->event_readset_out = readset_out;
if (!(writeset_out = mm_realloc(sop->event_writeset_out, sz))) {
- mm_free(readset_out);
+ /* We don't free readset_out here, since it was
+ * already successfully reallocated. The next time
+ * we call select_dispatch, the realloc will be a
+ * no-op. */
return (-1);
}
- sop->event_readset_out = readset_out;
sop->event_writeset_out = writeset_out;
sop->resize_out_sets = 0;
}
@@ -188,7 +193,6 @@ select_dispatch(struct event_base *base, struct timeval *tv)
return (0);
}
-
static int
select_resize(struct selectop *sop, int fdsz)
{
@@ -202,7 +206,12 @@ select_resize(struct selectop *sop, int fdsz)
goto error;
sop->event_readset_in = readset_in;
if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) {
- mm_free(readset_in);
+ /* Note that this will leave event_readset_in expanded.
+ * That's okay; we wouldn't want to free it, since that would
+ * change the semantics of select_resize from "expand the
+ * readset_in and writeset_in, or return -1" to "expand the
+ * *set_in members, or trash them and return -1."
+ */
goto error;
}
sop->event_writeset_in = writeset_in;