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

Contents of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Mon Sep 23 19:28:41 2002 UTC (21 years, 7 months ago) by nmav
Branch: MAIN
CVS Tags: BOAS_WITH_RANGES_AND_CGI
Changes since 1.2: +5 -4 lines
File MIME type: text/plain
Cleaned up the CGI handling. Now gunzip, indexer are treated like real cgis. Several other cleanups.

1 /*
2 * Boa, 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.2 2002/09/23 17:56:41 nmav Exp $*/
26
27 #include "boa.h"
28 #ifdef ENABLE_SMP
29 # include <pthread.h>
30
31 extern pthread_t father_id;
32
33 #endif
34
35 static void fdset_update( server_params *);
36
37 /* params->server_s[0] is the plain socket, while the
38 * params->server_s[1] is the ssl one.
39 */
40 void* select_loop(void* _params)
41 {
42 server_params* params = _params;
43
44 #ifdef ENABLE_SMP
45 pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL);
46 pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
47 #endif
48
49 FD_ZERO(&params->block_read_fdset);
50 FD_ZERO(&params->block_write_fdset);
51 /* set server_s and req_timeout */
52 params->req_timeout.tv_sec = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
53 params->req_timeout.tv_usec = 0l; /* reset timeout */
54
55 /* preset max_fd */
56 params->max_fd = -1;
57
58 while (1) {
59
60 if (params->sigchld_flag)
61 sigchld_run();
62
63 #ifdef ENABLE_SMP
64 /* Only the main thread handles signals.
65 */
66 if (pthread_equal( params->tid, father_id)) {
67 #endif
68 if (params->sighup_flag)
69 sighup_run();
70 if (params->sigalrm_flag)
71 sigalrm_run();
72 if (params->sigusr1_flag)
73 sigusr1_run();
74 if (params->sigterm_flag) {
75 if (params->sigterm_flag == 1) {
76 sigterm_stage1_run();
77 }
78 if (params->sigterm_flag == 2 && !params->request_ready && !params->request_block) {
79 sigterm_stage2_run();
80 }
81 }
82 #ifdef ENABLE_SMP
83 }
84 #endif
85
86 /* reset max_fd */
87 params->max_fd = -1;
88
89 if (params->request_block)
90 /* move selected req's from request_block to request_ready */
91 fdset_update( params);
92
93 /* any blocked req's move from request_ready to request_block */
94 if (params->server_s[0].socket != -1) process_requests(params, &params->server_s[0]);
95 #ifdef ENABLE_SSL
96 if (params->server_s[1].socket != -1) process_requests(params, &params->server_s[1]);
97 #endif
98
99 if (!params->sigterm_flag && params->total_connections < (max_connections - 10)) {
100 if (params->server_s[0].socket != -1) BOA_FD_SET(params->server_s[0].socket, &params->block_read_fdset); /* server always set */
101 #ifdef ENABLE_SSL
102 if (params->server_s[1].socket != -1) BOA_FD_SET(params->server_s[1].socket, &params->block_read_fdset); /* server always set */
103 #endif
104 }
105
106 params->req_timeout.tv_sec = ((params->request_ready) ? 0 :
107 (ka_timeout ? ka_timeout : REQUEST_TIMEOUT));
108 params->req_timeout.tv_usec = 0l; /* reset timeout */
109
110 if (select(params->max_fd + 1, &params->block_read_fdset,
111 &params->block_write_fdset, NULL,
112 ((params->request_ready || params->request_block) ? &params->req_timeout : NULL)) == -1) {
113 /* what is the appropriate thing to do here on EBADF */
114 if (errno == EINTR)
115 continue; /* while(1) */
116 else if (errno != EBADF) {
117 DIE("select");
118 }
119 }
120
121 time(&current_time);
122 if (params->server_s[0].socket != -1 && FD_ISSET(params->server_s[0].socket, &params->block_read_fdset))
123 params->server_s[0].pending_requests = 1;
124 #ifdef ENABLE_SSL
125 if (params->server_s[1].socket != -1 && FD_ISSET(params->server_s[1].socket, &params->block_read_fdset))
126 params->server_s[1].pending_requests = 1;
127 #endif
128 }
129
130 return NULL;
131 }
132
133 /*
134 * Name: fdset_update
135 *
136 * Description: iterate through the blocked requests, checking whether
137 * that file descriptor has been set by select. Update the fd_set to
138 * reflect current status.
139 *
140 * Here, we need to do some things:
141 * - keepalive timeouts simply close
142 * (this is special:: a keepalive timeout is a timeout where
143 keepalive is active but nothing has been read yet)
144 * - regular timeouts close + error
145 * - stuff in buffer and fd ready? write it out
146 * - fd ready for other actions? do them
147 */
148
149 static void fdset_update( server_params* params)
150 {
151 request *current, *next;
152
153 for(current = params->request_block;current;current = next) {
154 time_t time_since = current_time - current->time_last;
155 next = current->next;
156
157 /* hmm, what if we are in "the middle" of a request and not
158 * just waiting for a new one... perhaps check to see if anything
159 * has been read via header position, etc... */
160 if (current->kacount < ka_max && /* we *are* in a keepalive */
161 (time_since >= ka_timeout) && /* ka timeout */
162 !current->logline) /* haven't read anything yet */
163 current->status = DEAD; /* connection keepalive timed out */
164 else if (time_since > REQUEST_TIMEOUT) {
165 log_error_doc(current);
166 fputs("connection timed out\n", stderr);
167 current->status = DEAD;
168 }
169 if (current->buffer_end && current->status < DEAD) {
170 if (FD_ISSET(current->fd, &params->block_write_fdset))
171 ready_request( params, current);
172 else {
173 BOA_FD_SET(current->fd, &params->block_write_fdset);
174 }
175 } else {
176 switch (current->status) {
177 case WRITE:
178 case PIPE_WRITE:
179 if (FD_ISSET(current->fd, &params->block_write_fdset))
180 ready_request( params, current);
181 else {
182 BOA_FD_SET(current->fd, &params->block_write_fdset);
183 }
184 break;
185 case BODY_WRITE:
186 if (FD_ISSET(current->post_data_fd, &params->block_write_fdset))
187 ready_request( params, current);
188 else {
189 BOA_FD_SET(current->post_data_fd, &params->block_write_fdset);
190 }
191 break;
192 case PIPE_READ:
193 if (FD_ISSET(current->data_fd, &params->block_read_fdset))
194 ready_request( params, current);
195 else {
196 BOA_FD_SET(current->data_fd, &params->block_read_fdset);
197 }
198 break;
199 case DONE:
200 if (FD_ISSET(current->fd, &params->block_write_fdset))
201 ready_request( params, current);
202 else {
203 BOA_FD_SET(current->fd, &params->block_write_fdset);
204 }
205 break;
206 case DEAD:
207 ready_request( params, current);
208 break;
209 default:
210 if (FD_ISSET(current->fd, &params->block_read_fdset))
211 ready_request( params, current);
212 else {
213 BOA_FD_SET(current->fd, &params->block_read_fdset);
214 }
215 break;
216 }
217 }
218 current = next;
219 }
220 }
221

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26