Modify THTTPD to avoid poll() for write ready
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2026 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
b88b41f490
commit
cbee3431e0
@ -124,7 +124,7 @@ struct fdwatch_s *fdwatch_initialize(int nfds)
|
|||||||
|
|
||||||
fw->nfds = nfds;
|
fw->nfds = nfds;
|
||||||
|
|
||||||
fw->client = (struct fw_fd_s*)malloc(sizeof(struct fw_fd_s) * nfds);
|
fw->client = (void**)malloc(sizeof(void*) * nfds);
|
||||||
if (!fw->client)
|
if (!fw->client)
|
||||||
{
|
{
|
||||||
goto errout_with_allocations;
|
goto errout_with_allocations;
|
||||||
@ -175,7 +175,7 @@ void fdwatch_uninitialize(struct fdwatch_s *fw)
|
|||||||
|
|
||||||
/* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */
|
/* 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, int rw)
|
void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data)
|
||||||
{
|
{
|
||||||
nvdbg("fd: %d client_data: %p\n", fd, client_data);
|
nvdbg("fd: %d client_data: %p\n", fd, client_data);
|
||||||
|
|
||||||
@ -197,17 +197,8 @@ void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data, int rw)
|
|||||||
/* Save the new fd at the end of the list */
|
/* Save the new fd at the end of the list */
|
||||||
|
|
||||||
fw->pollfds[fw->nwatched].fd = fd;
|
fw->pollfds[fw->nwatched].fd = fd;
|
||||||
fw->client[fw->nwatched].rw = rw;
|
|
||||||
fw->client[fw->nwatched].data = client_data;
|
|
||||||
|
|
||||||
if (rw == FDW_READ)
|
|
||||||
{
|
|
||||||
fw->pollfds[fw->nwatched].events = POLLIN;
|
fw->pollfds[fw->nwatched].events = POLLIN;
|
||||||
}
|
fw->client[fw->nwatched] = client_data;
|
||||||
else
|
|
||||||
{
|
|
||||||
fw->pollfds[fw->nwatched].events = POLLOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment the count of watched descriptors */
|
/* Increment the count of watched descriptors */
|
||||||
|
|
||||||
@ -247,8 +238,7 @@ void fdwatch_del_fd(struct fdwatch_s *fw, int fd)
|
|||||||
if (pollndx != fw->nwatched)
|
if (pollndx != fw->nwatched)
|
||||||
{
|
{
|
||||||
fw->pollfds[pollndx] = fw->pollfds[fw->nwatched];
|
fw->pollfds[pollndx] = fw->pollfds[fw->nwatched];
|
||||||
fw->client[pollndx].rw = fw->client[fw->nwatched].rw;
|
fw->client[pollndx] = fw->client[fw->nwatched];
|
||||||
fw->client[pollndx].data = fw->client[fw->nwatched].data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,16 +320,9 @@ int fdwatch_check_fd(struct fdwatch_s *fw, int fd)
|
|||||||
|
|
||||||
pollndx = fdwatch_pollndx(fw, fd);
|
pollndx = fdwatch_pollndx(fw, fd);
|
||||||
if (pollndx >= 0 && (fw->pollfds[pollndx].revents & POLLERR) == 0)
|
if (pollndx >= 0 && (fw->pollfds[pollndx].revents & POLLERR) == 0)
|
||||||
{
|
|
||||||
if (fw->client[pollndx].rw == FDW_READ)
|
|
||||||
{
|
{
|
||||||
return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
|
return fw->pollfds[pollndx].revents & (POLLIN | POLLHUP | POLLNVAL);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return fw->pollfds[pollndx].revents & (POLLOUT | POLLHUP | POLLNVAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nvdbg("POLLERR fd: %d\n", fd);
|
nvdbg("POLLERR fd: %d\n", fd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -353,8 +336,8 @@ void *fdwatch_get_next_client_data(struct fdwatch_s *fw)
|
|||||||
return (void*)-1;
|
return (void*)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nvdbg("client_data[%d]: %p\n", fw->next, fw->client[fw->next].data);
|
nvdbg("client_data[%d]: %p\n", fw->next, fw->client[fw->next]);
|
||||||
return fw->client[fw->next++].data;
|
return fw->client[fw->next++];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate debugging statistics ndbg message. */
|
/* Generate debugging statistics ndbg message. */
|
||||||
|
@ -58,16 +58,10 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct fw_fd_s
|
|
||||||
{
|
|
||||||
uint8 rw; /* Read or write fd */
|
|
||||||
void *data; /* Retained client data */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fdwatch_s
|
struct fdwatch_s
|
||||||
{
|
{
|
||||||
struct pollfd *pollfds; /* Poll data */
|
struct pollfd *pollfds; /* Poll data */
|
||||||
struct fw_fd_s *client; /* Client data */
|
void **client; /* Client data */
|
||||||
uint8 *ready; /* The list of fds with activity */
|
uint8 *ready; /* The list of fds with activity */
|
||||||
uint8 nfds; /* The configured maximum number of fds */
|
uint8 nfds; /* The configured maximum number of fds */
|
||||||
uint8 nwatched; /* The number of fds currently watched */
|
uint8 nwatched; /* The number of fds currently watched */
|
||||||
@ -87,9 +81,9 @@ extern struct fdwatch_s *fdwatch_initialize(int nfds);
|
|||||||
|
|
||||||
extern void fdwatch_uninitialize(struct fdwatch_s *fw);
|
extern void fdwatch_uninitialize(struct fdwatch_s *fw);
|
||||||
|
|
||||||
/* Add a descriptor to the watch list. rw is either FDW_READ or FDW_WRITE. */
|
/* Add a descriptor to the watch list */
|
||||||
|
|
||||||
extern void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data, int rw);
|
extern void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data);
|
||||||
|
|
||||||
/* Delete a descriptor from the watch list. */
|
/* Delete a descriptor from the watch list. */
|
||||||
|
|
||||||
|
@ -586,8 +586,11 @@ static int send_err_file(httpd_conn *hc, int status, char *title, char *extrahea
|
|||||||
size_t nread;
|
size_t nread;
|
||||||
|
|
||||||
fp = fopen(filename, "r");
|
fp = fopen(filename, "r");
|
||||||
if (fp == (FILE *) 0)
|
if (fp == NULL)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
send_mime(hc, status, title, "", extraheads, "text/html; charset=%s",
|
send_mime(hc, status, title, "", extraheads, "text/html; charset=%s",
|
||||||
(off_t)-1, (time_t)0);
|
(off_t)-1, (time_t)0);
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -856,7 +859,7 @@ static int auth_check2(httpd_conn *hc, char *dirname)
|
|||||||
/* Open the password file. */
|
/* Open the password file. */
|
||||||
|
|
||||||
fp = fopen(authpath, "r");
|
fp = fopen(authpath, "r");
|
||||||
if (fp == (FILE *) 0)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
/* The file exists but we can't open it? Disallow access. */
|
/* The file exists but we can't open it? Disallow access. */
|
||||||
|
|
||||||
@ -1240,7 +1243,7 @@ static int vhost_map(httpd_conn *hc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Expands filename, deleting ..'s and leading /'s.
|
/* Expands filename, deleting ..'s and leading /'s.
|
||||||
* Returns the expanded path (pointer to static string), or (char*) 0 on
|
* Returns the expanded path (pointer to static string), or NULL on
|
||||||
* errors. Also returns, in the string pointed to by restP, any trailing
|
* errors. Also returns, in the string pointed to by restP, any trailing
|
||||||
* parts of the path that don't exist.
|
* parts of the path that don't exist.
|
||||||
*/
|
*/
|
||||||
@ -1466,7 +1469,7 @@ static char *bufgets(httpd_conn *hc)
|
|||||||
return &(hc->read_buf[i]);
|
return &(hc->read_buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (char *)0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void de_dotdot(char *file)
|
static void de_dotdot(char *file)
|
||||||
@ -1697,7 +1700,7 @@ static void cgi_kill(ClientData client_data, struct timeval *nowP)
|
|||||||
|
|
||||||
/* In case this isn't enough, schedule an uncatchable kill. */
|
/* In case this isn't enough, schedule an uncatchable kill. */
|
||||||
|
|
||||||
if (tmr_create(nowP, cgi_kill2, client_data, 5 * 1000L, 0) == (Timer *) 0)
|
if (tmr_create(nowP, cgi_kill2, client_data, 5 * 1000L, 0) == NULL)
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(cgi_kill2) failed\n");
|
ndbg("tmr_create(cgi_kill2) failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -1754,7 +1757,7 @@ static void ls_child(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
fp = fdopen(hc->conn_fd, "w");
|
fp = fdopen(hc->conn_fd, "w");
|
||||||
if (fp == (FILE *) 0)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
ndbg("fdopen: %d\n", errno);
|
ndbg("fdopen: %d\n", errno);
|
||||||
INTERNALERROR("fdopen");
|
INTERNALERROR("fdopen");
|
||||||
@ -1905,7 +1908,7 @@ static void ls_child(int argc, char **argv)
|
|||||||
|
|
||||||
/* Get time string. */
|
/* Get time string. */
|
||||||
|
|
||||||
now = time((time_t *) 0);
|
now = time(NULL);
|
||||||
timestr = ctime(&lsb.st_mtime);
|
timestr = ctime(&lsb.st_mtime);
|
||||||
timestr[0] = timestr[4];
|
timestr[0] = timestr[4];
|
||||||
timestr[1] = timestr[5];
|
timestr[1] = timestr[5];
|
||||||
@ -2001,7 +2004,7 @@ static int ls(httpd_conn *hc)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
dirp = opendir(hc->expnfilename);
|
dirp = opendir(hc->expnfilename);
|
||||||
if (dirp == (DIR *) 0)
|
if (dirp == NULL)
|
||||||
{
|
{
|
||||||
ndbg("opendir %s: %d\n", hc->expnfilename, errno);
|
ndbg("opendir %s: %d\n", hc->expnfilename, errno);
|
||||||
httpd_send_err(hc, 404, err404title, "", err404form, hc->encodedurl);
|
httpd_send_err(hc, 404, err404title, "", err404form, hc->encodedurl);
|
||||||
@ -2056,7 +2059,7 @@ static int ls(httpd_conn *hc)
|
|||||||
|
|
||||||
#if CONFIG_THTTPD_CGI_TIMELIMIT > 0
|
#if CONFIG_THTTPD_CGI_TIMELIMIT > 0
|
||||||
client_data.i = child;
|
client_data.i = child;
|
||||||
if (tmr_create((struct timeval *)0, cgi_kill, client_data, CONFIG_THTTPD_CGI_TIMELIMIT * 1000L, 0) == (Timer *) 0)
|
if (tmr_create(NULL, cgi_kill, client_data, CONFIG_THTTPD_CGI_TIMELIMIT * 1000L, 0) == NULL)
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(cgi_kill ls) failed\n");
|
ndbg("tmr_create(cgi_kill ls) failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -2233,7 +2236,7 @@ static FAR char **make_argp(httpd_conn *hc)
|
|||||||
argp = NEW(char *, strlen(hc->query) + 2);
|
argp = NEW(char *, strlen(hc->query) + 2);
|
||||||
if (!argp)
|
if (!argp)
|
||||||
{
|
{
|
||||||
return (char **)0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
argp[0] = strrchr(hc->expnfilename, '/');
|
argp[0] = strrchr(hc->expnfilename, '/');
|
||||||
@ -2273,7 +2276,7 @@ static FAR char **make_argp(httpd_conn *hc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argp[argn] = (char *)0;
|
argp[argn] = NULL;
|
||||||
return argp;
|
return argp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2360,7 +2363,7 @@ static inline int cgi_interpose_output(httpd_conn *hc, int rfd, char *inbuffer,
|
|||||||
struct cgi_outbuffer_s *hdr)
|
struct cgi_outbuffer_s *hdr)
|
||||||
{
|
{
|
||||||
ssize_t nbytes_read;
|
ssize_t nbytes_read;
|
||||||
char *br;
|
char *br = NULL;
|
||||||
int status;
|
int status;
|
||||||
const char *title;
|
const char *title;
|
||||||
char *cp;
|
char *cp;
|
||||||
@ -2462,7 +2465,7 @@ static inline int cgi_interpose_output(httpd_conn *hc, int rfd, char *inbuffer,
|
|||||||
status = atoi(cp);
|
status = atoi(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cp = strstr(hdr->buffer, "Status:")) != (char *)0 &&
|
if ((cp = strstr(hdr->buffer, "Status:")) != NULL &&
|
||||||
cp < br && (cp == hdr->buffer || *(cp - 1) == '\012'))
|
cp < br && (cp == hdr->buffer || *(cp - 1) == '\012'))
|
||||||
{
|
{
|
||||||
cp += 7;
|
cp += 7;
|
||||||
@ -2470,7 +2473,7 @@ static inline int cgi_interpose_output(httpd_conn *hc, int rfd, char *inbuffer,
|
|||||||
status = atoi(cp);
|
status = atoi(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cp = strstr(hdr->buffer, "Location:")) != (char *)0 &&
|
if ((cp = strstr(hdr->buffer, "Location:")) != NULL &&
|
||||||
cp < br && (cp == hdr->buffer || *(cp - 1) == '\012'))
|
cp < br && (cp == hdr->buffer || *(cp - 1) == '\012'))
|
||||||
{
|
{
|
||||||
status = 302;
|
status = 302;
|
||||||
@ -2624,8 +2627,8 @@ static int cgi_child(int argc, char **argv)
|
|||||||
boolean outdone;
|
boolean outdone;
|
||||||
int child;
|
int child;
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
int wfd;
|
int wfd = -1;
|
||||||
int rfd;
|
int rfd = -1;
|
||||||
int fd;
|
int fd;
|
||||||
int ret;
|
int ret;
|
||||||
int err = 1;
|
int err = 1;
|
||||||
@ -2782,8 +2785,7 @@ static int cgi_child(int argc, char **argv)
|
|||||||
|
|
||||||
#if CONFIG_THTTPD_CGI_TIMELIMIT > 0
|
#if CONFIG_THTTPD_CGI_TIMELIMIT > 0
|
||||||
client_data.i = child;
|
client_data.i = child;
|
||||||
if (tmr_create((struct timeval *)0, cgi_kill, client_data,
|
if (tmr_create(NULL, cgi_kill, client_data, CONFIG_THTTPD_CGI_TIMELIMIT * 1000L, 0) == NULL)
|
||||||
CONFIG_THTTPD_CGI_TIMELIMIT * 1000L, 0) == (Timer *) 0)
|
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(cgi_kill child) failed\n");
|
ndbg("tmr_create(cgi_kill child) failed\n");
|
||||||
goto errout_with_watch;
|
goto errout_with_watch;
|
||||||
@ -2792,8 +2794,8 @@ static int cgi_child(int argc, char **argv)
|
|||||||
|
|
||||||
/* Add the read descriptors to the watch */
|
/* Add the read descriptors to the watch */
|
||||||
|
|
||||||
fdwatch_add_fd(fw, hc->conn_fd, NULL, FDW_READ);
|
fdwatch_add_fd(fw, hc->conn_fd, NULL);
|
||||||
fdwatch_add_fd(fw, rfd, NULL, FDW_READ);
|
fdwatch_add_fd(fw, rfd, NULL);
|
||||||
|
|
||||||
/* Then perform the interposition */
|
/* Then perform the interposition */
|
||||||
|
|
||||||
@ -2964,7 +2966,7 @@ static int really_check_referer(httpd_conn *hc)
|
|||||||
char *cp1;
|
char *cp1;
|
||||||
char *cp2;
|
char *cp2;
|
||||||
char *cp3;
|
char *cp3;
|
||||||
static char *refhost = (char *)0;
|
static char *refhost = NULL;
|
||||||
static size_t refhost_size = 0;
|
static size_t refhost_size = 0;
|
||||||
char *lp;
|
char *lp;
|
||||||
|
|
||||||
@ -3824,8 +3826,7 @@ int httpd_parse_request(httpd_conn *hc)
|
|||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(hc->hdrhost, '/') != (char *)0 ||
|
if (strchr(hc->hdrhost, '/') != NULL || hc->hdrhost[0] == '.')
|
||||||
hc->hdrhost[0] == '.')
|
|
||||||
{
|
{
|
||||||
BADREQUEST("hdrhost");
|
BADREQUEST("hdrhost");
|
||||||
httpd_send_err(hc, 400, httpd_err400title, "", httpd_err400form, "");
|
httpd_send_err(hc, 400, httpd_err400title, "", httpd_err400form, "");
|
||||||
@ -3903,7 +3904,7 @@ int httpd_parse_request(httpd_conn *hc)
|
|||||||
if (cp)
|
if (cp)
|
||||||
{
|
{
|
||||||
cp_dash = strchr(cp + 1, '-');
|
cp_dash = strchr(cp + 1, '-');
|
||||||
if (cp_dash != (char *)0 && cp_dash != cp + 1)
|
if (cp_dash != NULL && cp_dash != cp + 1)
|
||||||
{
|
{
|
||||||
*cp_dash = '\0';
|
*cp_dash = '\0';
|
||||||
hc->got_range = TRUE;
|
hc->got_range = TRUE;
|
||||||
@ -4125,7 +4126,7 @@ int httpd_parse_request(httpd_conn *hc)
|
|||||||
|
|
||||||
void httpd_close_conn(httpd_conn *hc, struct timeval *nowP)
|
void httpd_close_conn(httpd_conn *hc, struct timeval *nowP)
|
||||||
{
|
{
|
||||||
if (hc->file_fd)
|
if (hc->file_fd >= 0)
|
||||||
{
|
{
|
||||||
(void)close(hc->file_fd);
|
(void)close(hc->file_fd);
|
||||||
hc->file_fd = -1;
|
hc->file_fd = -1;
|
||||||
@ -4312,7 +4313,7 @@ int httpd_start_request(httpd_conn *hc, struct timeval *nowP)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
cp = expand_filename(indexname, &pi, hc->tildemapped);
|
cp = expand_filename(indexname, &pi, hc->tildemapped);
|
||||||
if (cp == (char *)0 || pi[0] != '\0')
|
if (cp == NULL || pi[0] != '\0')
|
||||||
{
|
{
|
||||||
INTERNALERROR(indexname);
|
INTERNALERROR(indexname);
|
||||||
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
httpd_send_err(hc, 500, err500title, "", err500form, hc->encodedurl);
|
||||||
|
@ -157,7 +157,7 @@ static void shut_down(void)
|
|||||||
int cnum;
|
int cnum;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
(void)gettimeofday(&tv, (struct timezone *)0);
|
(void)gettimeofday(&tv, NULL);
|
||||||
logstats(&tv);
|
logstats(&tv);
|
||||||
for (cnum = 0; cnum < AVAILABLE_FDS; ++cnum)
|
for (cnum = 0; cnum < AVAILABLE_FDS; ++cnum)
|
||||||
{
|
{
|
||||||
@ -166,19 +166,19 @@ static void shut_down(void)
|
|||||||
httpd_close_conn(connects[cnum].hc, &tv);
|
httpd_close_conn(connects[cnum].hc, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connects[cnum].hc != (httpd_conn *) 0)
|
if (connects[cnum].hc != NULL)
|
||||||
{
|
{
|
||||||
httpd_destroy_conn(connects[cnum].hc);
|
httpd_destroy_conn(connects[cnum].hc);
|
||||||
free((void *)connects[cnum].hc);
|
free((void *)connects[cnum].hc);
|
||||||
--httpd_conn_count;
|
--httpd_conn_count;
|
||||||
connects[cnum].hc = (httpd_conn *) 0;
|
connects[cnum].hc = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hs)
|
if (hs)
|
||||||
{
|
{
|
||||||
httpd_server *ths = hs;
|
httpd_server *ths = hs;
|
||||||
hs = (httpd_server *) 0;
|
hs = NULL;
|
||||||
if (ths->listen_fd != -1)
|
if (ths->listen_fd != -1)
|
||||||
{
|
{
|
||||||
fdwatch_del_fd(fw, ths->listen_fd);
|
fdwatch_del_fd(fw, ths->listen_fd);
|
||||||
@ -233,7 +233,7 @@ static int handle_newconnect(struct timeval *tv, int listen_fd)
|
|||||||
if (!conn->hc)
|
if (!conn->hc)
|
||||||
{
|
{
|
||||||
conn->hc = NEW(httpd_conn, 1);
|
conn->hc = NEW(httpd_conn, 1);
|
||||||
if (conn->hc == (httpd_conn *) 0)
|
if (conn->hc == NULL)
|
||||||
{
|
{
|
||||||
ndbg("out of memory allocating an httpd_conn\n");
|
ndbg("out of memory allocating an httpd_conn\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -282,7 +282,7 @@ static int handle_newconnect(struct timeval *tv, int listen_fd)
|
|||||||
/* Set the connection file descriptor to no-delay mode */
|
/* Set the connection file descriptor to no-delay mode */
|
||||||
|
|
||||||
httpd_set_ndelay(conn->hc->conn_fd);
|
httpd_set_ndelay(conn->hc->conn_fd);
|
||||||
fdwatch_add_fd(fw, conn->hc->conn_fd, conn, FDW_READ);
|
fdwatch_add_fd(fw, conn->hc->conn_fd, conn);
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
|
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
|
||||||
++stats_connections;
|
++stats_connections;
|
||||||
@ -422,9 +422,7 @@ static void handle_read(struct connect_s *conn, struct timeval *tv)
|
|||||||
|
|
||||||
conn->conn_state = CNST_SENDING;
|
conn->conn_state = CNST_SENDING;
|
||||||
client_data.p = conn;
|
client_data.p = conn;
|
||||||
|
|
||||||
fdwatch_del_fd(fw, hc->conn_fd);
|
fdwatch_del_fd(fw, hc->conn_fd);
|
||||||
fdwatch_add_fd(fw, hc->conn_fd, conn, FDW_WRITE);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
errout_with_400:
|
errout_with_400:
|
||||||
@ -466,6 +464,13 @@ static void handle_send(struct connect_s *conn, struct timeval *tv)
|
|||||||
int nwritten;
|
int nwritten;
|
||||||
int nread;
|
int nread;
|
||||||
|
|
||||||
|
/* Read until the entire file is sent -- this could take awhile!! */
|
||||||
|
|
||||||
|
while (conn->offset < conn->end_offset)
|
||||||
|
{
|
||||||
|
nvdbg("offset: %d end_offset: %d bytes_sent: %d\n",
|
||||||
|
conn->offset, conn->end_offset, conn->hc->bytes_sent);
|
||||||
|
|
||||||
/* Fill the rest of the response buffer with file data */
|
/* Fill the rest of the response buffer with file data */
|
||||||
|
|
||||||
nread = read_buffer(conn);
|
nread = read_buffer(conn);
|
||||||
@ -504,19 +509,12 @@ static void handle_send(struct connect_s *conn, struct timeval *tv)
|
|||||||
conn->hc->bytes_sent += nwritten;
|
conn->hc->bytes_sent += nwritten;
|
||||||
nvdbg("Wrote %d bytes\n", nwritten);
|
nvdbg("Wrote %d bytes\n", nwritten);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Are we done? */
|
/* The file transfer is complete -- finish the connection */
|
||||||
|
|
||||||
nvdbg("offset: %d end_offset: %d bytes_sent: %d\n",
|
|
||||||
conn->offset, conn->end_offset, conn->hc->bytes_sent);
|
|
||||||
|
|
||||||
if (conn->offset >= conn->end_offset)
|
|
||||||
{
|
|
||||||
/* This connection is finished! */
|
|
||||||
|
|
||||||
nvdbg("Finish connection\n");
|
nvdbg("Finish connection\n");
|
||||||
finish_connection(conn, tv);
|
finish_connection(conn, tv);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
errout_clear_connection:
|
errout_clear_connection:
|
||||||
@ -561,7 +559,7 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv)
|
|||||||
{
|
{
|
||||||
ClientData client_data;
|
ClientData client_data;
|
||||||
|
|
||||||
if (conn->wakeup_timer != (Timer *) 0)
|
if (conn->wakeup_timer != NULL)
|
||||||
{
|
{
|
||||||
tmr_cancel(conn->wakeup_timer);
|
tmr_cancel(conn->wakeup_timer);
|
||||||
conn->wakeup_timer = 0;
|
conn->wakeup_timer = 0;
|
||||||
@ -584,7 +582,7 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv)
|
|||||||
/* If we were already lingering, shut down for real */
|
/* If we were already lingering, shut down for real */
|
||||||
|
|
||||||
tmr_cancel(conn->linger_timer);
|
tmr_cancel(conn->linger_timer);
|
||||||
conn->linger_timer = (Timer *) 0;
|
conn->linger_timer = NULL;
|
||||||
conn->hc->should_linger = FALSE;
|
conn->hc->should_linger = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,17 +595,17 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv)
|
|||||||
|
|
||||||
conn->conn_state = CNST_LINGERING;
|
conn->conn_state = CNST_LINGERING;
|
||||||
close(conn->hc->conn_fd);
|
close(conn->hc->conn_fd);
|
||||||
fdwatch_add_fd(fw, conn->hc->conn_fd, conn, FDW_READ);
|
fdwatch_add_fd(fw, conn->hc->conn_fd, conn);
|
||||||
client_data.p = conn;
|
client_data.p = conn;
|
||||||
|
|
||||||
if (conn->linger_timer != (Timer *) 0)
|
if (conn->linger_timer != NULL)
|
||||||
{
|
{
|
||||||
ndbg("replacing non-null linger_timer!\n");
|
ndbg("replacing non-null linger_timer!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->linger_timer =
|
conn->linger_timer =
|
||||||
tmr_create(tv, linger_clear_connection, client_data, CONFIG_THTTPD_LINGER_MSEC, 0);
|
tmr_create(tv, linger_clear_connection, client_data, CONFIG_THTTPD_LINGER_MSEC, 0);
|
||||||
if (conn->linger_timer == (Timer *) 0)
|
if (conn->linger_timer == NULL)
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(linger_clear_connection) failed\n");
|
ndbg("tmr_create(linger_clear_connection) failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -630,7 +628,7 @@ static void really_clear_connection(struct connect_s *conn, struct timeval *tv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
httpd_close_conn(conn->hc, tv);
|
httpd_close_conn(conn->hc, tv);
|
||||||
if (conn->linger_timer != (Timer *) 0)
|
if (conn->linger_timer != NULL)
|
||||||
{
|
{
|
||||||
tmr_cancel(conn->linger_timer);
|
tmr_cancel(conn->linger_timer);
|
||||||
conn->linger_timer = 0;
|
conn->linger_timer = 0;
|
||||||
@ -679,7 +677,7 @@ static void linger_clear_connection(ClientData client_data, struct timeval *nowP
|
|||||||
struct connect_s *conn;
|
struct connect_s *conn;
|
||||||
|
|
||||||
conn = (struct connect_s *) client_data.p;
|
conn = (struct connect_s *) client_data.p;
|
||||||
conn->linger_timer = (Timer *) 0;
|
conn->linger_timer = NULL;
|
||||||
really_clear_connection(conn, nowP);
|
really_clear_connection(conn, nowP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,9 +696,9 @@ static void logstats(struct timeval *nowP)
|
|||||||
long up_secs;
|
long up_secs;
|
||||||
long stats_secs;
|
long stats_secs;
|
||||||
|
|
||||||
if (nowP == (struct timeval *)0)
|
if (!nowP)
|
||||||
{
|
{
|
||||||
(void)gettimeofday(&tv, (struct timezone *)0);
|
(void)gettimeofday(&tv, NULL);
|
||||||
nowP = &tv;
|
nowP = &tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,9 +820,7 @@ int thttpd_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Set up the occasional timer */
|
/* Set up the occasional timer */
|
||||||
|
|
||||||
if (tmr_create
|
if (tmr_create(NULL, occasional, JunkClientData, CONFIG_THTTPD_OCCASIONAL_MSEC * 1000L, 1) == NULL)
|
||||||
((struct timeval *)0, occasional, JunkClientData, CONFIG_THTTPD_OCCASIONAL_MSEC * 1000L,
|
|
||||||
1) == (Timer *) 0)
|
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(occasional) failed\n");
|
ndbg("tmr_create(occasional) failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -832,8 +828,7 @@ int thttpd_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Set up the idle timer */
|
/* Set up the idle timer */
|
||||||
|
|
||||||
if (tmr_create((struct timeval *)0, idle, JunkClientData, 5 * 1000L, 1) ==
|
if (tmr_create(NULL, idle, JunkClientData, 5 * 1000L, 1) == NULL)
|
||||||
(Timer *) 0)
|
|
||||||
{
|
{
|
||||||
ndbg("tmr_create(idle) failed\n");
|
ndbg("tmr_create(idle) failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -855,9 +850,9 @@ int thttpd_main(int argc, char **argv)
|
|||||||
/* Initialize our connections table */
|
/* Initialize our connections table */
|
||||||
|
|
||||||
connects = NEW(struct connect_s, AVAILABLE_FDS);
|
connects = NEW(struct connect_s, AVAILABLE_FDS);
|
||||||
if (connects == (struct connect_s *) 0)
|
if (connects == NULL)
|
||||||
{
|
{
|
||||||
ndbg("out of memory allocating a struct connect_s\n");
|
ndbg("Out of memory allocating a struct connect_s\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,7 +860,7 @@ int thttpd_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
connects[cnum].conn_state = CNST_FREE;
|
connects[cnum].conn_state = CNST_FREE;
|
||||||
connects[cnum].next_free_connect = cnum + 1;
|
connects[cnum].next_free_connect = cnum + 1;
|
||||||
connects[cnum].hc = (httpd_conn *) 0;
|
connects[cnum].hc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
connects[AVAILABLE_FDS - 1].next_free_connect = -1; /* end of link list */
|
connects[AVAILABLE_FDS - 1].next_free_connect = -1; /* end of link list */
|
||||||
@ -873,16 +868,18 @@ int thttpd_main(int argc, char **argv)
|
|||||||
num_connects = 0;
|
num_connects = 0;
|
||||||
httpd_conn_count = 0;
|
httpd_conn_count = 0;
|
||||||
|
|
||||||
if (hs != (httpd_server *) 0)
|
if (hs != NULL)
|
||||||
{
|
{
|
||||||
if (hs->listen_fd != -1)
|
if (hs->listen_fd != -1)
|
||||||
fdwatch_add_fd(fw, hs->listen_fd, (void *)0, FDW_READ);
|
{
|
||||||
|
fdwatch_add_fd(fw, hs->listen_fd, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
|
|
||||||
nvdbg("Entering the main loop\n");
|
nvdbg("Entering the main loop\n");
|
||||||
(void)gettimeofday(&tv, (struct timezone *)0);
|
(void)gettimeofday(&tv, NULL);
|
||||||
while ((!terminate) || num_connects > 0)
|
while ((!terminate) || num_connects > 0)
|
||||||
{
|
{
|
||||||
/* Do the fd watch */
|
/* Do the fd watch */
|
||||||
@ -901,7 +898,7 @@ int thttpd_main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)gettimeofday(&tv, (struct timezone *)0);
|
(void)gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
if (num_ready == 0)
|
if (num_ready == 0)
|
||||||
{
|
{
|
||||||
@ -946,13 +943,36 @@ int thttpd_main(int argc, char **argv)
|
|||||||
switch (conn->conn_state)
|
switch (conn->conn_state)
|
||||||
{
|
{
|
||||||
case CNST_READING:
|
case CNST_READING:
|
||||||
|
{
|
||||||
handle_read(conn, &tv);
|
handle_read(conn, &tv);
|
||||||
|
|
||||||
|
/* If a GET request was received and a file is ready to
|
||||||
|
* be sent, then fall through to send the file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (conn->conn_state != CNST_SENDING)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case CNST_SENDING:
|
case CNST_SENDING:
|
||||||
|
{
|
||||||
|
/* Send a file -- this really should be performed on a
|
||||||
|
* separate thread to keep the serve from locking up during
|
||||||
|
* the write.
|
||||||
|
*/
|
||||||
|
|
||||||
handle_send(conn, &tv);
|
handle_send(conn, &tv);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CNST_LINGERING:
|
case CNST_LINGERING:
|
||||||
|
{
|
||||||
|
/* Linger close the connection */
|
||||||
|
|
||||||
handle_linger(conn, &tv);
|
handle_linger(conn, &tv);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user