summaryrefslogtreecommitdiff
path: root/poll/unix
diff options
context:
space:
mode:
authorrbb <rbb@13f79535-47bb-0310-9956-ffa450edef68>2002-08-02 18:12:04 +0000
committerrbb <rbb@13f79535-47bb-0310-9956-ffa450edef68>2002-08-02 18:12:04 +0000
commit515c78f43939a6bc543ec3b0f326ac0ade70ea99 (patch)
treea44a08b82ca6b03168e6e4e9e877d25d98e47720 /poll/unix
parentbf215916e904e284e5306f7de28307e104aaa6c2 (diff)
downloadlibapr-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')
-rw-r--r--poll/unix/poll.c25
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;
}