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

Contents of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations)
Mon Oct 21 18:46:26 2002 UTC (21 years, 5 months ago) by nmav
Branch: MAIN
Changes since 1.8: +30 -52 lines
File MIME type: text/plain
Added several stuff from Boa 0.94.14rc1

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26