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

Annotation of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (hide annotations)
Sun Jan 26 11:25:39 2003 UTC (21 years, 2 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_6_without_hic, hydra_0_1_7, hydra_0_1_6, hydra_0_1_4, hydra_0_1_8, HEAD
Changes since 1.13: +142 -125 lines
File MIME type: text/plain
Better large file support (now uses the included autoconf macros).
(++some indentation)

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26