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

Annotation of /hydra/src/select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations)
Wed Jan 22 07:51:50 2003 UTC (21 years, 2 months ago) by nmav
Branch: MAIN
Changes since 1.12: +9 -10 lines
File MIME type: text/plain
merged changes from 0.1.x branch.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26