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

Annotation of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations)
Mon Sep 23 19:28:41 2002 UTC (21 years, 6 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 nmav 1.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 nmav 1.3 /* $Id: select.c,v 1.2 2002/09/23 17:56:41 nmav Exp $*/
26 nmav 1.1
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 nmav 1.3
60     if (params->sigchld_flag)
61     sigchld_run();
62    
63 nmav 1.1 #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 nmav 1.2 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 nmav 1.1
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 nmav 1.2 #ifdef ENABLE_SSL
102 nmav 1.1 if (params->server_s[1].socket != -1) BOA_FD_SET(params->server_s[1].socket, &params->block_read_fdset); /* server always set */
103 nmav 1.2 #endif
104 nmav 1.1 }
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 nmav 1.2 #ifdef ENABLE_SSL
125 nmav 1.1 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 nmav 1.2 #endif
128 nmav 1.1 }
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