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

Annotation of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations)
Wed Oct 2 19:26:15 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_6
Changes since 1.6: +2 -2 lines
File MIME type: text/plain
Better use of limits. If getrlimit() returns a cur limit less than max limit, we increase the cur limit.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26