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

Contents of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12.2.1 - (show annotations)
Sat Dec 14 08:54:16 2002 UTC (21 years, 4 months ago) by nmav
Branch: hydra_0_1_0_patches
CVS Tags: hydra_0_1_3, hydra_0_1_2, hydra_0_1_1
Changes since 1.12: +9 -10 lines
File MIME type: text/plain
Corrected a bug that made an idle server, to reject the
first connection due to a timeout.

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.12 2002/10/26 20:58:48 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) process_requests(params, &params->server_s[0]);
60 #ifdef ENABLE_SSL
61 if (params->server_s[1].socket != -1) process_requests(params, &params->server_s[1]);
62 #endif
63
64 if (!params->sigterm_flag) {
65 if (params->server_s[0].socket != -1) BOA_FD_SET(req, params->server_s[0].socket, &params->block_read_fdset);
66 #ifdef ENABLE_SSL
67 if (params->server_s[1].socket != -1) BOA_FD_SET(req, params->server_s[1].socket, &params->block_read_fdset);
68 #endif
69 }
70
71 SET_TIMEOUT( params->req_timeout.tv_sec, 1, -1);
72 params->req_timeout.tv_usec = 0l; /* reset timeout */
73
74 if (params->req_timeout.tv_sec == -1) timeout = NULL;
75 else timeout = params->req_timeout;
76
77 if (select(params->max_fd + 1, &params->block_read_fdset,
78 &params->block_write_fdset, NULL, timeout) == -1)
79 {
80 /* what is the appropriate thing to do here on EBADF */
81 if (errno == EINTR)
82 continue; /* while(1) */
83 else if (errno != EBADF) {
84 DIE("select");
85 }
86 }
87
88 if (params->server_s[0].socket != -1 && FD_ISSET(params->server_s[0].socket, &params->block_read_fdset))
89 params->server_s[0].pending_requests = 1;
90 #ifdef ENABLE_SSL
91 if (params->server_s[1].socket != -1 && FD_ISSET(params->server_s[1].socket, &params->block_read_fdset))
92 params->server_s[1].pending_requests = 1;
93 #endif
94 }
95
96 return NULL;
97 }
98
99 /*
100 * Name: fdset_update
101 *
102 * Description: iterate through the blocked requests, checking whether
103 * that file descriptor has been set by select. Update the fd_set to
104 * reflect current status.
105 *
106 * Here, we need to do some things:
107 * - keepalive timeouts simply close
108 * (this is special:: a keepalive timeout is a timeout where
109 keepalive is active but nothing has been read yet)
110 * - regular timeouts close + error
111 * - stuff in buffer and fd ready? write it out
112 * - fd ready for other actions? do them
113 */
114
115 static void fdset_update( server_params* params)
116 {
117 request *current, *next;
118
119 for(current = params->request_block;current;current = next) {
120 time_t time_since = current_time - current->time_last;
121 next = current->next;
122
123 /* hmm, what if we are in "the middle" of a request and not
124 * just waiting for a new one... perhaps check to see if anything
125 * has been read via header position, etc... */
126 if (current->kacount < ka_max && /* we *are* in a keepalive */
127 (time_since >= ka_timeout) && /* ka timeout */
128 !current->logline) /* haven't read anything yet */
129 current->status = DEAD; /* connection keepalive timed out */
130 else if (time_since > REQUEST_TIMEOUT) {
131 log_error_doc(current);
132 fprintf(stderr, "connection timed out (%d seconds)\n", time_since);
133 current->status = DEAD;
134 }
135 if (current->buffer_end && current->status < DEAD) {
136 if (FD_ISSET(current->fd, &params->block_write_fdset))
137 ready_request( params, current);
138 else {
139 BOA_FD_SET( current, current->fd, &params->block_write_fdset);
140 }
141 } else {
142 switch (current->status) {
143 case IOSHUFFLE:
144 #ifndef HAVE_SENDFILE
145 if (current->buffer_end - current->buffer_start == 0) {
146 if (FD_ISSET(current->data_fd, &block_read_fdset))
147 ready_request(params, current);
148 break;
149 }
150 #endif
151 case WRITE:
152 case PIPE_WRITE:
153 if (FD_ISSET(current->fd, &params->block_write_fdset))
154 ready_request( params, current);
155 else {
156 BOA_FD_SET( current, current->fd, &params->block_write_fdset);
157 }
158 break;
159 case BODY_WRITE:
160 if (FD_ISSET(current->post_data_fd.fds[1], &params->block_write_fdset))
161 ready_request( params, current);
162 else {
163 BOA_FD_SET( current, current->post_data_fd.fds[1], &params->block_write_fdset);
164 }
165 break;
166 case PIPE_READ:
167 if (FD_ISSET(current->data_fd, &params->block_read_fdset))
168 ready_request( params, current);
169 else {
170 BOA_FD_SET( current, current->data_fd, &params->block_read_fdset);
171 }
172 break;
173 case DONE:
174 if (FD_ISSET(current->fd, &params->block_write_fdset))
175 ready_request( params, current);
176 else {
177 BOA_FD_SET( current, current->fd, &params->block_write_fdset);
178 }
179 break;
180 case DEAD:
181 ready_request( params, current);
182 break;
183 default:
184 if (FD_ISSET(current->fd, &params->block_read_fdset))
185 ready_request( params, current);
186 else {
187 BOA_FD_SET( current, current->fd, &params->block_read_fdset);
188 }
189 break;
190 }
191 }
192 current = next;
193 }
194 }
195
196 #endif /* USE_POLL */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26