diff options
author | rbb <rbb@13f79535-47bb-0310-9956-ffa450edef68> | 2002-08-02 18:12:04 +0000 |
---|---|---|
committer | rbb <rbb@13f79535-47bb-0310-9956-ffa450edef68> | 2002-08-02 18:12:04 +0000 |
commit | 515c78f43939a6bc543ec3b0f326ac0ade70ea99 (patch) | |
tree | a44a08b82ca6b03168e6e4e9e877d25d98e47720 /poll/unix/poll.c | |
parent | bf215916e904e284e5306f7de28307e104aaa6c2 (diff) | |
download | libapr-515c78f43939a6bc543ec3b0f326ac0ade70ea99.tar.gz |
Remove the memory leak from the apr_poll implementation. On all systems,
this will support any number of files/sockets. On modern systems, this
will allocate on the stack. On older systems we fall back to malloc/free.
Note: We will rarely ever use malloc/free.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@63769 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll/unix/poll.c')
-rw-r--r-- | poll/unix/poll.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/poll/unix/poll.c b/poll/unix/poll.c index 9b25504d1..68ccde8db 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -111,24 +111,25 @@ static apr_int16_t get_revent(apr_int16_t event) APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num, apr_int32_t *nsds, apr_interval_time_t timeout) { + int i; +#ifdef HAVE_VLA + struct pollfd pollset[num]; +#elif defined(HAVE_ALLOCA) + struct pollfd *pollset = alloca(sizeof(pollfd) * num); +#else struct pollfd tmp_pollset[SMALL_POLLSET_LIMIT]; struct pollfd *pollset; - int i; if (num <= SMALL_POLLSET_LIMIT) { pollset = tmp_pollset; } else { - /* XXX There are two problems with this code: it leaks - * memory, and it requires an O(n)-time loop to copy - * n descriptors from the apr_pollfd_t structs into - * the pollfd structs. At the moment, it's best suited - * for use with fewer than SMALL_POLLSET_LIMIT - * descriptors. + /* This does require O(n) to copy the descriptors to the internal + * mapping. */ - pollset = apr_palloc(aprset->p, - sizeof(struct pollfd) * num); + pollset = malloc(sizeof(struct pollfd) * num); } +#endif for (i = 0; i < num; i++) { if (aprset[i].desc_type == APR_POLL_SOCKET) { pollset[i].fd = aprset[i].desc.s->socketdes; @@ -150,6 +151,12 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num, aprset[i].rtnevents = get_revent(pollset[i].revents); } +#if !defined(HAVE_VLA) && !defined(HAVE_ALLOCA) + if (num > SMALL_POLLSET_LIMIT) { + free(pollset); + } +#endif + if ((*nsds) < 0) { return errno; } |