diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-01-12 21:41:58 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-01-12 21:41:58 -0500 |
commit | 8b0afe96eb3436bfa286a1fb2059f137458139b7 (patch) | |
tree | c825dac40f65a3c411ecb15dc9e0267f13458998 /select.c | |
parent | b647e0bc94a6c1a32767f00b6c19a22483720c4f (diff) | |
parent | 0c0ec0be2ba977b8133294e27b076a65a2d65711 (diff) | |
download | libevent-8b0afe96eb3436bfa286a1fb2059f137458139b7.tar.gz |
Merge remote branch 'origin/patches-2.0'
Diffstat (limited to 'select.c')
-rw-r--r-- | select.c | 36 |
1 files changed, 27 insertions, 9 deletions
@@ -91,6 +91,7 @@ const struct eventop selectops = { }; static int select_resize(struct selectop *sop, int fdsz); +static void select_free_selectop(struct selectop *sop); static void * select_init(struct event_base *base) @@ -100,7 +101,10 @@ select_init(struct event_base *base) if (!(sop = mm_calloc(1, sizeof(struct selectop)))) return (NULL); - select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask)); + if (select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask))) { + select_free_selectop(sop); + return (NULL); + } evsig_init(base); @@ -129,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; } @@ -186,7 +193,6 @@ select_dispatch(struct event_base *base, struct timeval *tv) return (0); } - static int select_resize(struct selectop *sop, int fdsz) { @@ -199,8 +205,15 @@ select_resize(struct selectop *sop, int fdsz) if ((readset_in = mm_realloc(sop->event_readset_in, fdsz)) == NULL) goto error; 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) { + /* 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; sop->resize_out_sets = 1; @@ -293,11 +306,8 @@ select_del(struct event_base *base, int fd, short old, short events, void *p) } static void -select_dealloc(struct event_base *base) +select_free_selectop(struct selectop *sop) { - struct selectop *sop = base->evbase; - - evsig_dealloc(base); if (sop->event_readset_in) mm_free(sop->event_readset_in); if (sop->event_writeset_in) @@ -310,3 +320,11 @@ select_dealloc(struct event_base *base) memset(sop, 0, sizeof(struct selectop)); mm_free(sop); } + +static void +select_dealloc(struct event_base *base) +{ + evsig_dealloc(base); + + select_free_selectop(base->evbase); +} |