summaryrefslogtreecommitdiff
path: root/nuttx/netutils
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-08-02 18:12:22 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-08-02 18:12:22 +0000
commit287259e702344f08c101996a47349e049bc7af27 (patch)
tree520683a9a87fd6063916044edfa746f66fbea155 /nuttx/netutils
parent074c81dde834a56b4be1b8bcc5c8132aa9e64f6a (diff)
downloadpx4-nuttx-287259e702344f08c101996a47349e049bc7af27.tar.gz
px4-nuttx-287259e702344f08c101996a47349e049bc7af27.tar.bz2
px4-nuttx-287259e702344f08c101996a47349e049bc7af27.zip
Fix fdwatch problems; reduce fdwatch memory usage
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2010 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/netutils')
-rw-r--r--nuttx/netutils/thttpd/fdwatch.c271
-rw-r--r--nuttx/netutils/thttpd/fdwatch.h27
2 files changed, 132 insertions, 166 deletions
diff --git a/nuttx/netutils/thttpd/fdwatch.c b/nuttx/netutils/thttpd/fdwatch.c
index 724631918..45673e3f4 100644
--- a/nuttx/netutils/thttpd/fdwatch.c
+++ b/nuttx/netutils/thttpd/fdwatch.c
@@ -82,6 +82,25 @@ static long nwatches = 0;
* Private Functions
****************************************************************************/
+static int fdwatch_pollndx(FAR struct fdwatch_s *fw, int fd)
+{
+ int pollndx;
+
+ /* Get the index associated with the fd */
+
+ for (pollndx = 0; pollndx < fw->nwatched; pollndx++)
+ {
+ if (fw->pollfds[pollndx].fd == fd)
+ {
+ nvdbg("pollndx: %d\n", pollndx);
+ return pollndx;
+ }
+ }
+
+ ndbg("No poll index for fd %d: %d\n", fd);
+ return -1;
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -90,8 +109,7 @@ static long nwatches = 0;
struct fdwatch_s *fdwatch_initialize(int nfds)
{
- struct fdwatch_s *fw;
- int i;
+ FAR struct fdwatch_s *fw;
/* Allocate the fdwatch data structure */
@@ -106,46 +124,23 @@ struct fdwatch_s *fdwatch_initialize(int nfds)
fw->nfds = nfds;
- fw->fd_rw = (int*)malloc(sizeof(int) * nfds);
- if (!fw->fd_rw)
- {
- goto errout_with_allocations;
- }
-
- fw->fd_data = (void**)malloc(sizeof(void*) * nfds);
- if (!fw->fd_data)
+ fw->client = (struct fw_fd_s*)malloc(sizeof(struct fw_fd_s) * nfds);
+ if (!fw->client)
{
goto errout_with_allocations;
}
- for (i = 0; i < nfds; ++i)
- {
- fw->fd_rw[i] = -1;
- }
-
fw->pollfds = (struct pollfd*)malloc(sizeof(struct pollfd) * nfds);
if (!fw->pollfds)
{
goto errout_with_allocations;
}
- fw->poll_pollndx = (int*)malloc(sizeof(int) * nfds);
- if (!fw->poll_pollndx)
- {
- goto errout_with_allocations;
- }
-
- fw->poll_rfdidx = (int*)malloc(sizeof(int) * nfds);
- if (!fw->poll_rfdidx)
+ fw->ready = (uint8*)malloc(sizeof(uint8) * nfds);
+ if (!fw->ready)
{
goto errout_with_allocations;
}
-
- for (i = 0; i < nfds; i++)
- {
- fw->pollfds[i].fd = fw->poll_pollndx[i] = -1;
- }
-
return fw;
errout_with_allocations:
@@ -159,14 +154,9 @@ void fdwatch_uninitialize(struct fdwatch_s *fw)
{
if (fw)
{
- if (fw->fd_rw)
+ if (fw->client)
{
- free(fw->fd_rw);
- }
-
- if (fw->fd_data)
- {
- free(fw->fd_data);
+ free(fw->client);
}
if (fw->pollfds)
@@ -174,14 +164,9 @@ void fdwatch_uninitialize(struct fdwatch_s *fw)
free(fw->pollfds);
}
- if (fw->poll_pollndx)
- {
- free(fw->poll_pollndx);
- }
-
- if (fw->poll_rfdidx)
+ if (fw->ready)
{
- free(fw->poll_rfdidx);
+ free(fw->ready);
}
free(fw);
@@ -192,101 +177,80 @@ void fdwatch_uninitialize(struct fdwatch_s *fw)
void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data, int rw)
{
- int fdndx;
+ nvdbg("fd: %d\n", fd);
#ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS ||
- fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
- fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] != -1)
+ fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds)
{
ndbg("Received bad fd (%d)\n", fd);
return;
}
#endif
- if (fw->npoll_fds >= fw->nfds)
+ if (fw->nwatched >= fw->nfds)
{
ndbg("too many fds\n");
return;
}
- /* Get the socket index associated with the fd */
-
- fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
-
/* Save the new fd at the end of the list */
- fw->pollfds[fw->npoll_fds].fd = fd;
- switch (rw)
+ fw->pollfds[fw->nwatched].fd = fd;
+ fw->client[fw->nwatched].rw = rw;
+ fw->client[fw->nwatched].data = client_data;
+
+ if (rw == FDW_READ)
{
- default:
- case FDW_READ:
- fw->pollfds[fw->npoll_fds].events = POLLIN;
- break;
-
- case FDW_WRITE:
- fw->pollfds[fw->npoll_fds].events = POLLOUT;
- break;
+ fw->pollfds[fw->nwatched].events = POLLIN;
+ }
+ else
+ {
+ fw->pollfds[fw->nwatched].events = POLLOUT;
}
- /* Save the new index and increment the cound of watched descriptors */
-
- fw->poll_pollndx[fdndx] = fw->npoll_fds;
- fw->npoll_fds++;
+ /* Increment the count of watched descriptors */
- fw->fd_rw[fdndx] = rw;
- fw->fd_data[fdndx] = client_data;
+ fw->nwatched++;
}
/* Remove a descriptor from the watch list. */
void fdwatch_del_fd(struct fdwatch_s *fw, int fd)
{
- int fdndx;
int pollndx;
- int tmpndx;
+
+ nvdbg("fd: %d\n", fd);
#ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS ||
- fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
- fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
+ fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds)
{
ndbg("Received bad fd: %d\n", fd);
return;
}
#endif
- /* Get the socket index associated with the fd and then the poll
- * index associated with that.
- */
-
- fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
- pollndx = fw->poll_pollndx[fdndx];
+ /* Get the index associated with the fd */
-#ifdef CONFIG_DEBUG
- if (pollndx < 0 || pollndx >= fw->nfds)
+ pollndx = fdwatch_pollndx(fw, fd);
+ if (pollndx >= 0)
{
- ndbg("Bad poll index: %d\n", pollndx);
- return;
- }
-#endif
-
- /* Decrement the number of fds in the poll table */
+ /* Decrement the number of fds in the poll table */
- fw->npoll_fds--;
+ fw->nwatched--;
- /* Replace the deleted one with the one at the the end
- * of the list.
- */
-
- tmpndx = fw->pollfds[pollndx].fd - CONFIG_NFILE_DESCRIPTORS;
- fw->pollfds[pollndx] = fw->pollfds[fw->npoll_fds];
- fw->poll_pollndx[tmpndx] = fw->poll_pollndx[fdndx];;
- fw->pollfds[fw->npoll_fds].fd = -1;
- fw->poll_pollndx[fdndx] = -1;
+ /* Replace the deleted one with the one at the the end
+ * of the list.
+ */
- fw->fd_rw[fdndx] = -1;
- fw->fd_data[fdndx] = NULL;
+ if (pollndx != fw->nwatched)
+ {
+ fw->pollfds[pollndx] = fw->pollfds[fw->nwatched];
+ fw->client[pollndx].rw = fw->client[fw->nwatched].rw;
+ fw->client[pollndx].data = fw->client[fw->nwatched].data;
+ }
+ }
}
/* Do the watch. Return value is the number of descriptors that are ready,
@@ -296,7 +260,6 @@ void fdwatch_del_fd(struct fdwatch_s *fw, int fd)
int fdwatch(struct fdwatch_s *fw, long timeout_msecs)
{
- int rfndx;
int ret;
int i;
@@ -304,100 +267,92 @@ int fdwatch(struct fdwatch_s *fw, long timeout_msecs)
nwatches++;
#endif
- ret = poll(fw->pollfds, fw->npoll_fds, (int)timeout_msecs);
- if (ret <= 0)
- {
- return ret;
- }
+ /* Wait for activity on any of the desciptors. When poll() returns, ret
+ * will hold the number of descriptors with activity (or zero on a timeout
+ * or <0 on an error.
+ */
- rfndx = 0;
- for (i = 0; i < fw->npoll_fds; i++)
+ nvdbg("Waiting...\n");
+ fw->nactive = 0;
+ fw->next = 0;
+ ret = poll(fw->pollfds, fw->nwatched, (int)timeout_msecs);
+ nvdbg("Awakened: %d\n", ret);
+
+ /* Look through all of the descriptors and make a list of all of them than
+ * have activity.
+ */
+
+ if (ret > 0)
{
- if (fw->pollfds[i].revents & (POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL))
+ for (i = 0; i < fw->nwatched; i++)
{
- fw->poll_rfdidx[rfndx++] = fw->pollfds[i].fd;
- if (rfndx == ret)
+ /* Is there activity on this descriptor? */
+
+ if (fw->pollfds[i].revents & (POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL))
{
- break;
+ /* Yes... save it in a shorter list */
+
+ fw->ready[fw->nactive++] = fw->pollfds[i].fd;
+ if (fw->nactive == ret)
+ {
+ /* We have all of them, break out early */
+
+ break;
+ }
}
}
}
- return rfndx;
+ /* Return the number of descriptors with activity */
+
+ nvdbg("nactive: %d\n", fw->nactive);
+ return ret;
}
/* Check if a descriptor was ready. */
int fdwatch_check_fd(struct fdwatch_s *fw, int fd)
{
- int fdndx;
int pollndx;
+ nvdbg("fd: %d\n", fd);
+
#ifdef CONFIG_DEBUG
if (fd < CONFIG_NFILE_DESCRIPTORS ||
- fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds ||
- fw->fd_rw[fd-CONFIG_NFILE_DESCRIPTORS] == -1)
+ fd >= CONFIG_NFILE_DESCRIPTORS + fw->nfds)
{
ndbg("Bad fd: %d\n", fd);
return 0;
}
#endif
- /* Get the socket index associated with the fd and then the poll
- * index associated with that.
- */
-
- fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
- pollndx = fw->poll_pollndx[fdndx];
-
-#ifdef CONFIG_DEBUG
- if (pollndx < 0 || pollndx >= fw->nfds)
- {
- ndbg("Bad poll index: %d\n", pollndx);
- return 0;
- }
-#endif
+ /* Get the index associated with the fd */
- if (fw->pollfds[pollndx].revents & POLLERR)
+ pollndx = fdwatch_pollndx(fw, fd);
+ if (pollndx >= 0 && (fw->pollfds[pollndx].revents & POLLERR) == 0)
{
- return 0;
+ if (fw->client[pollndx].rw == FDW_READ)
+ {
+ return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
+ }
+ else
+ {
+ return fw->pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
+ }
}
- switch (fw->fd_rw[fdndx])
- {
- case FDW_READ:
- return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
-
- case FDW_WRITE:
- return fw->pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
-
- default:
- break;
- }
+ nvdbg("POLLERR fd: %d\n", fd);
return 0;
}
void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
{
- int rfndx;
- int fdndx;
- int fd;
-
-#ifdef CONFIG_DEBUG
- if (rfndx < 0 || rfndx >= fw->nfds)
+ if (fw->next >= fw->nfds)
{
- ndbg("Bad rfndx: %d\n", rfndx);
+ ndbg("All client data returned: %d\n", fw->next);
return NULL;
}
-#endif
-
- fd = fw->poll_rfdidx[rfndx];
- fdndx = fd-CONFIG_NFILE_DESCRIPTORS;
- if (fdndx < 0 || fdndx >= fw->nfds)
- {
- return NULL;
- }
- return fw->fd_data[fdndx];
+ return fw->client[fw->next++].data;
}
/* Generate debugging statistics ndbg message. */
@@ -406,7 +361,9 @@ void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
void fdwatch_logstats(struct fdwatch_s *fw, long secs)
{
if (secs > 0)
- ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs);
+ {
+ ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs);
+ }
nwatches = 0;
}
#endif
diff --git a/nuttx/netutils/thttpd/fdwatch.h b/nuttx/netutils/thttpd/fdwatch.h
index 65a6704ce..4f960b56c 100644
--- a/nuttx/netutils/thttpd/fdwatch.h
+++ b/nuttx/netutils/thttpd/fdwatch.h
@@ -33,12 +33,15 @@
*
****************************************************************************/
+#ifndef __NETUTILS_THTTPD_FDWATCH_H
+#define __NETUTILS_THTTPD_FDWATCH_H
+
/****************************************************************************
* Included Files
****************************************************************************/
-#ifndef __NETUTILS_THTTPD_FDWATCH_H
-#define __NETUTILS_THTTPD_FDWATCH_H
+#include <nuttx/config.h>
+#include <sys/types.h>
/****************************************************************************
* Pre-Processor Definitions
@@ -55,15 +58,21 @@
* Private Types
****************************************************************************/
+struct fw_fd_s
+{
+ uint8 rw; /* Read or write fd */
+ void *data; /* Retained client data */
+};
+
struct fdwatch_s
{
- int *fd_rw;
- void **fd_data;
- struct pollfd *pollfds;
- int *poll_pollndx;
- int *poll_rfdidx;
- int nfds;
- int npoll_fds;
+ struct pollfd *pollfds; /* Poll data */
+ struct fw_fd_s *client; /* Client data */
+ uint8 *ready; /* The list of fds with activity */
+ uint8 nfds; /* The configured maximum number of fds */
+ uint8 nwatched; /* The number of fds currently watched */
+ uint8 nactive; /* The number of fds with activity */
+ uint8 next; /* The index to the next client data */
};
/****************************************************************************