Handle resize failures in the select backend better.

This commit is contained in:
Nick Mathewson 2011-01-07 13:18:09 -05:00
parent 3f8d22a123
commit 83e805a415

View File

@ -100,7 +100,9 @@ select_init(struct event_base *base)
return (NULL); return (NULL);
if (select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask))) { 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); return (NULL);
} }
@ -131,11 +133,14 @@ select_dispatch(struct event_base *base, struct timeval *tv)
size_t sz = sop->event_fdsz; size_t sz = sop->event_fdsz;
if (!(readset_out = mm_realloc(sop->event_readset_out, sz))) if (!(readset_out = mm_realloc(sop->event_readset_out, sz)))
return (-1); return (-1);
sop->event_readset_out = readset_out;
if (!(writeset_out = mm_realloc(sop->event_writeset_out, sz))) { 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); return (-1);
} }
sop->event_readset_out = readset_out;
sop->event_writeset_out = writeset_out; sop->event_writeset_out = writeset_out;
sop->resize_out_sets = 0; sop->resize_out_sets = 0;
} }
@ -188,7 +193,6 @@ select_dispatch(struct event_base *base, struct timeval *tv)
return (0); return (0);
} }
static int static int
select_resize(struct selectop *sop, int fdsz) select_resize(struct selectop *sop, int fdsz)
{ {
@ -202,7 +206,12 @@ select_resize(struct selectop *sop, int fdsz)
goto error; goto error;
sop->event_readset_in = readset_in; sop->event_readset_in = readset_in;
if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) { 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; goto error;
} }
sop->event_writeset_in = writeset_in; sop->event_writeset_in = writeset_in;