STATIC_ARRAY_LIST(server_arraylist, struct rtr_server);
STATIC_ARRAY_LIST(client_arraylist, struct rtr_client);
-STATIC_ARRAY_LIST(pollfd_arraylist, struct pollfd);
static struct server_arraylist servers;
static struct client_arraylist clients;
}
static void
-apply_pollfds(struct pollfd_arraylist *pollfds, unsigned int nclients)
+delete_dead_clients(void)
+{
+ unsigned int src;
+ unsigned int dst;
+
+ for (src = 0, dst = 0; src < clients.len; src++) {
+ if (clients.array[src].fd != -1) {
+ clients.array[dst] = clients.array[src];
+ dst++;
+ }
+ }
+
+ clients.len = dst;
+}
+
+static void
+apply_pollfds(struct pollfd *pollfds, unsigned int nclients)
{
struct pollfd *pfd;
struct rtr_server *server;
unsigned int i;
for (i = 0; i < servers.len; i++) {
- pfd = &pollfds->array[i];
+ pfd = &pollfds[i];
server = &servers.array[i];
/* PR_DEBUG_MSG("pfd:%d server:%d", pfd->fd, server->fd); */
}
for (i = 0; i < nclients; i++) {
- pfd = &pollfds->array[servers.len + i];
+ pfd = &pollfds[servers.len + i];
client = &clients.array[i];
/* PR_DEBUG_MSG("pfd:%d client:%d", pfd->fd, client->fd); */
}
}
- /* TODO clean up client array */
+ delete_dead_clients();
}
static enum poll_verdict
fddb_poll(void)
{
- struct pollfd_arraylist pollfds;
+ struct pollfd *pollfds; /* array */
struct rtr_server *server;
struct rtr_client *client;
unsigned int i;
int error;
- pollfd_arraylist_init(&pollfds);
-
- pollfds.len = servers.len + clients.len;
- pollfds.capacity = pollfds.len;
- pollfds.array = calloc(pollfds.len, sizeof(struct pollfd));
- if (pollfds.array == NULL) {
+ pollfds = calloc(servers.len + clients.len, sizeof(struct pollfd));
+ if (pollfds == NULL) {
pr_enomem();
return PV_RETRY;
}
ARRAYLIST_FOREACH(&servers, server, i)
- init_pollfd(&pollfds.array[i], server->fd);
+ init_pollfd(&pollfds[i], server->fd);
ARRAYLIST_FOREACH(&clients, client, i)
- init_pollfd(&pollfds.array[servers.len + i], client->fd);
+ init_pollfd(&pollfds[servers.len + i], client->fd);
- error = poll(pollfds.array, pollfds.len, 1000);
+ error = poll(pollfds, servers.len + clients.len, 1000);
if (stop_server_thread)
goto stop;
/* New connections */
for (i = 0; i < servers.len; i++) {
/* This fd is a listening socket. */
- fd = &pollfds.array[i];
+ fd = &pollfds[i];
/* PR_DEBUG_MSG("Server %u: fd:%d revents:%x",
i, fd->fd, fd->revents); */
/* Client requests */
for (i = 0; i < nclients; i++) {
/* This fd is a client handler socket. */
- fd = &pollfds.array[servers.len + i];
+ fd = &pollfds[servers.len + i];
/* PR_DEBUG_MSG("Client %u: fd:%d revents:%x", i, fd->fd,
fd->revents); */
}
lock_mutex();
- apply_pollfds(&pollfds, nclients);
+ apply_pollfds(pollfds, nclients);
unlock_mutex();
/* Fall through */
success:
- pollfd_arraylist_cleanup(&pollfds, NULL);
+ free(pollfds);
return PV_CONTINUE;
retry:
- pollfd_arraylist_cleanup(&pollfds, NULL);
+ free(pollfds);
return PV_RETRY;
stop:
- pollfd_arraylist_cleanup(&pollfds, NULL);
+ free(pollfds);
return PV_STOP;
}