/[hydra]/hydra/src/select.c
ViewVC logotype

Contents of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (show annotations)
Sun Jan 26 11:25:39 2003 UTC (21 years, 2 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_6_without_hic, hydra_0_1_7, hydra_0_1_6, hydra_0_1_4, hydra_0_1_8, HEAD
Changes since 1.13: +142 -125 lines
File MIME type: text/plain
Better large file support (now uses the included autoconf macros).
(++some indentation)

1 /*
2 * Hydra, an http server
3 * Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
4 * Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com>
5 * Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
6 * Some changes Copyright (C) 1996-2002 Jon Nelson <jnelson@boa.org>
7 * Portions Copyright (C) 2002 Nikos Mavroyanopoulos <nmav@gnutls.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 1, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25 /* $Id: select.c,v 1.13 2003/01/22 07:51:50 nmav Exp $*/
26
27 #include "boa.h"
28 #include "loop_signals.h"
29
30 #ifndef USE_POLL
31
32 static void fdset_update(server_params *);
33
34 /* params->server_s[0] is the plain socket, while the
35 * params->server_s[1] is the ssl one.
36 */
37 void *select_loop(void *_params)
38 {
39 server_params *params = _params;
40 struct timeval *timeout;
41
42 FD_ZERO(&params->block_read_fdset);
43 FD_ZERO(&params->block_write_fdset);
44
45 /* preset max_fd */
46
47 while (1) {
48
49 handle_signals(params);
50
51 /* reset max_fd */
52 params->max_fd = -1;
53
54 if (params->request_block)
55 /* move selected req's from request_block to request_ready */
56 fdset_update(params);
57
58 /* any blocked req's move from request_ready to request_block */
59 if (params->server_s[0].socket != -1)
60 process_requests(params, &params->server_s[0]);
61 #ifdef ENABLE_SSL
62 if (params->server_s[1].socket != -1)
63 process_requests(params, &params->server_s[1]);
64 #endif
65
66 if (!params->sigterm_flag) {
67 if (params->server_s[0].socket != -1)
68 BOA_FD_SET(req, params->server_s[0].socket,
69 &params->block_read_fdset);
70 #ifdef ENABLE_SSL
71 if (params->server_s[1].socket != -1)
72 BOA_FD_SET(req, params->server_s[1].socket,
73 &params->block_read_fdset);
74 #endif
75 }
76
77 SET_TIMEOUT(params->req_timeout.tv_sec, 1, -1);
78 params->req_timeout.tv_usec = 0l; /* reset timeout */
79
80 if (params->req_timeout.tv_sec == -1)
81 timeout = NULL;
82 else
83 timeout = params->req_timeout;
84
85 if (select(params->max_fd + 1, &params->block_read_fdset,
86 &params->block_write_fdset, NULL, timeout) == -1) {
87 /* what is the appropriate thing to do here on EBADF */
88 if (errno == EINTR)
89 continue; /* while(1) */
90 else if (errno != EBADF) {
91 DIE("select");
92 }
93 }
94
95 if (params->server_s[0].socket != -1
96 && FD_ISSET(params->server_s[0].socket,
97 &params->block_read_fdset))
98 params->server_s[0].pending_requests = 1;
99 #ifdef ENABLE_SSL
100 if (params->server_s[1].socket != -1
101 && FD_ISSET(params->server_s[1].socket,
102 &params->block_read_fdset))
103 params->server_s[1].pending_requests = 1;
104 #endif
105 }
106
107 return NULL;
108 }
109
110 /*
111 * Name: fdset_update
112 *
113 * Description: iterate through the blocked requests, checking whether
114 * that file descriptor has been set by select. Update the fd_set to
115 * reflect current status.
116 *
117 * Here, we need to do some things:
118 * - keepalive timeouts simply close
119 * (this is special:: a keepalive timeout is a timeout where
120 keepalive is active but nothing has been read yet)
121 * - regular timeouts close + error
122 * - stuff in buffer and fd ready? write it out
123 * - fd ready for other actions? do them
124 */
125
126 static void fdset_update(server_params * params)
127 {
128 request *current, *next;
129
130 for (current = params->request_block; current; current = next) {
131 time_t time_since = current_time - current->time_last;
132 next = current->next;
133
134 /* hmm, what if we are in "the middle" of a request and not
135 * just waiting for a new one... perhaps check to see if anything
136 * has been read via header position, etc... */
137 if (current->kacount < ka_max && /* we *are* in a keepalive */
138 (time_since >= ka_timeout) && /* ka timeout */
139 !current->logline) /* haven't read anything yet */
140 current->status = DEAD; /* connection keepalive timed out */
141 else if (time_since > REQUEST_TIMEOUT) {
142 log_error_doc(current);
143 fprintf(stderr, "connection timed out (%d seconds)\n",
144 time_since);
145 current->status = DEAD;
146 }
147 if (current->buffer_end && current->status < DEAD) {
148 if (FD_ISSET(current->fd, &params->block_write_fdset))
149 ready_request(params, current);
150 else {
151 BOA_FD_SET(current, current->fd, &params->block_write_fdset);
152 }
153 } else {
154 switch (current->status) {
155 case IOSHUFFLE:
156 #ifndef HAVE_SENDFILE
157 if (current->buffer_end - current->buffer_start == 0) {
158 if (FD_ISSET(current->data_fd, &block_read_fdset))
159 ready_request(params, current);
160 break;
161 }
162 #endif
163 case WRITE:
164 case PIPE_WRITE:
165 if (FD_ISSET(current->fd, &params->block_write_fdset))
166 ready_request(params, current);
167 else {
168 BOA_FD_SET(current, current->fd,
169 &params->block_write_fdset);
170 }
171 break;
172 case BODY_WRITE:
173 if (FD_ISSET
174 (current->post_data_fd.fds[1], &params->block_write_fdset))
175 ready_request(params, current);
176 else {
177 BOA_FD_SET(current, current->post_data_fd.fds[1],
178 &params->block_write_fdset);
179 }
180 break;
181 case PIPE_READ:
182 if (FD_ISSET(current->data_fd, &params->block_read_fdset))
183 ready_request(params, current);
184 else {
185 BOA_FD_SET(current, current->data_fd,
186 &params->block_read_fdset);
187 }
188 break;
189 case DONE:
190 if (FD_ISSET(current->fd, &params->block_write_fdset))
191 ready_request(params, current);
192 else {
193 BOA_FD_SET(current, current->fd,
194 &params->block_write_fdset);
195 }
196 break;
197 case DEAD:
198 ready_request(params, current);
199 break;
200 default:
201 if (FD_ISSET(current->fd, &params->block_read_fdset))
202 ready_request(params, current);
203 else {
204 BOA_FD_SET(current, current->fd, &params->block_read_fdset);
205 }
206 break;
207 }
208 }
209 current = next;
210 }
211 }
212
213 #endif /* USE_POLL */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26