Huang Qi ffd256d32b Remove unused header files across multiple source files
Clean up code by removing redundant and unused header file includes that were identified through static analysis.
This improves code readability and reduces unnecessary dependencies.

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
2025-01-10 21:42:00 +08:00

347 lines
9.3 KiB
C

/****************************************************************************
* apps/netutils/thttpd/fdwatch.c
*
* SPDX-License-Identifier: BSD-2-Clause
* SPDX-FileCopyrightText: 2009 Gregory Nutt. All rights reserved.
* SPDX-FileCopyrightText: 1999,2000 by Jef Poskanzer <jef@mail.acme.com>.
* SPDX-FileContributor: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include <debug.h>
#include <poll.h>
#include "config.h"
#include "thttpd_alloc.h"
#include "fdwatch.h"
#ifdef CONFIG_THTTPD
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
/* Debug output from this file is normally suppressed. If enabled, be aware
* that output to stdout will interfere with CGI programs.
*/
#ifdef CONFIG_THTTPD_FDWATCH_DEBUG
# define fwerr nerr
# define fwinfo ninfo
#else
# define fwerr _none
# define fwinfo _none
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
#ifdef CONFIG_THTTPD_FDWATCH_DEBUG
static void fdwatch_dump(const char *msg, FAR struct fdwatch_s *fw)
{
int i;
fwinfo("%s\n", msg);
fwinfo("nwatched: %d nfds: %d\n", fw->nwatched, fw->nfds);
for (i = 0; i < fw->nwatched; i++)
{
fwinfo("%2d.pollfds: {fd: %d events: %02x revents: %02x} client: %p\n",
i + 1, fw->pollfds[i].fd, fw->pollfds[i].events,
fw->pollfds[i].revents, fw->client[i]);
}
fwinfo("nactive: %d next: %d\n", fw->nactive, fw->next);
for (i = 0; i < fw->nactive; i++)
{
fwinfo("%2d. %d active\n", i, fw->ready[i]);
}
}
#else
# define fdwatch_dump(m,f)
#endif
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)
{
fwinfo("pollndx: %d\n", pollndx);
return pollndx;
}
}
fwerr("ERROR: No poll index for fd %d\n", fd);
return -1;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/* Initialize the fdwatch data structures. Returns -1 on failure. */
struct fdwatch_s *fdwatch_initialize(int nfds)
{
FAR struct fdwatch_s *fw;
/* Allocate the fdwatch data structure */
fw = (struct fdwatch_s *)zalloc(sizeof(struct fdwatch_s));
if (!fw)
{
fwerr("ERROR: Failed to allocate fdwatch\n");
return NULL;
}
/* Initialize the fdwatch data structures. */
fw->nfds = nfds;
fw->client = (void **)httpd_malloc(sizeof(void *) * nfds);
if (!fw->client)
{
goto errout_with_allocations;
}
fw->pollfds = (struct pollfd *)httpd_malloc(sizeof(struct pollfd) * nfds);
if (!fw->pollfds)
{
goto errout_with_allocations;
}
fw->ready = (uint8_t *)httpd_malloc(sizeof(uint8_t) * nfds);
if (!fw->ready)
{
goto errout_with_allocations;
}
fdwatch_dump("Initial state:", fw);
return fw;
errout_with_allocations:
fdwatch_uninitialize(fw);
return NULL;
}
/* Uninitialize the fwdatch data structure */
void fdwatch_uninitialize(struct fdwatch_s *fw)
{
if (fw)
{
fdwatch_dump("Uninitializing:", fw);
if (fw->client)
{
httpd_free(fw->client);
}
if (fw->pollfds)
{
httpd_free(fw->pollfds);
}
if (fw->ready)
{
httpd_free(fw->ready);
}
httpd_free(fw);
}
}
/* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */
void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data)
{
fwinfo("fd: %d client_data: %p\n", fd, client_data);
fdwatch_dump("Before adding:", fw);
if (fw->nwatched >= fw->nfds)
{
fwerr("ERROR: too many fds\n");
return;
}
/* Save the new fd at the end of the list */
fw->pollfds[fw->nwatched].fd = fd;
fw->pollfds[fw->nwatched].events = POLLIN;
fw->client[fw->nwatched] = client_data;
/* Increment the count of watched descriptors */
fw->nwatched++;
fdwatch_dump("After adding:", fw);
}
/* Remove a descriptor from the watch list. */
void fdwatch_del_fd(struct fdwatch_s *fw, int fd)
{
int pollndx;
fwinfo("fd: %d\n", fd);
fdwatch_dump("Before deleting:", fw);
/* Get the index associated with the fd */
pollndx = fdwatch_pollndx(fw, fd);
if (pollndx >= 0)
{
/* Decrement the number of fds in the poll table */
fw->nwatched--;
/* Replace the deleted one with the one at the end
* of the list.
*/
if (pollndx != fw->nwatched)
{
fw->pollfds[pollndx] = fw->pollfds[fw->nwatched];
fw->client[pollndx] = fw->client[fw->nwatched];
}
}
fdwatch_dump("After deleting:", fw);
}
/* Do the watch. Return value is the number of descriptors that are ready,
* or 0 if the timeout expired, or -1 on errors. A timeout of INFTIM means
* wait indefinitely.
*/
int fdwatch(struct fdwatch_s *fw, long timeout_msecs)
{
int ret;
int i;
/* Wait for activity on any of the descriptors. When poll() returns, ret
* will hold the number of descriptors with activity (or zero on a timeout
* or <0 on an error.
*/
fdwatch_dump("Before waiting:", fw);
fwinfo("Waiting... (timeout %ld)\n", timeout_msecs);
fw->nactive = 0;
fw->next = 0;
ret = poll(fw->pollfds, fw->nwatched, (int)timeout_msecs);
fwinfo("Awakened: %d\n", ret);
/* Look through all of the descriptors and make a list of all of them than
* have activity.
*/
if (ret > 0)
{
for (i = 0; i < fw->nwatched; i++)
{
/* Is there activity on this descriptor? */
if (fw->pollfds[i].revents &
(POLLIN | POLLERR | POLLHUP | POLLNVAL))
{
/* Yes... save it in a shorter list */
fwinfo("pollndx: %d fd: %d revents: %08" PRIx32 "\n",
i, fw->pollfds[i].fd, fw->pollfds[i].revents);
fw->ready[fw->nactive++] = fw->pollfds[i].fd;
if (fw->nactive == ret)
{
/* We have all of them, break out early */
break;
}
}
}
}
/* Return the number of descriptors with activity */
fwinfo("nactive: %d\n", fw->nactive);
fdwatch_dump("After wakeup:", fw);
return ret;
}
/* Check if a descriptor was ready. */
int fdwatch_check_fd(struct fdwatch_s *fw, int fd)
{
int pollndx;
fwinfo("fd: %d\n", fd);
fdwatch_dump("Checking:", fw);
/* Get the index associated with the fd */
pollndx = fdwatch_pollndx(fw, fd);
if (pollndx >= 0 && (fw->pollfds[pollndx].revents & POLLERR) == 0)
{
return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
}
fwinfo("POLLERR fd: %d\n", fd);
return 0;
}
void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
{
fdwatch_dump("Before getting client data:", fw);
if (fw->next >= fw->nwatched)
{
fwinfo("All client data returned: %d\n", fw->next);
return (void *)(uintptr_t)-1;
}
fwinfo("client_data[%d]: %p\n", fw->next, fw->client[fw->next]);
return fw->client[fw->next++];
}
#endif /* CONFIG_THTTPD */