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

Annotation of /hydra/src/poll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Mon Oct 21 19:10:31 2002 UTC (21 years, 5 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_8, hydra_0_0_9, hydra_0_1_0, hydra_0_0_10
Branch point for: hydra_0_1_0_patches
Changes since 1.1: +13 -13 lines
File MIME type: text/plain
some corrections in the poll code.

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-2000 Jon Nelson <jnelson@boa.org>
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 1, or (at your option)
11     * any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     *
22     */
23    
24 nmav 1.2 /* $Id: poll.c,v 1.1 2002/10/21 18:46:26 nmav Exp $*/
25 nmav 1.1
26     #include "boa.h"
27     #include "loop_signals.h"
28    
29     #ifdef USE_POLL
30    
31     int pending_requests;
32    
33     void update_blocked(server_params* params, struct pollfd pfd1[]);
34    
35 nmav 1.2 void* select_loop(void* _params)
36 nmav 1.1 {
37     server_params* params = _params;
38     struct pollfd pfd1[2][MAX_FD];
39     short which = 0, other = 1, temp;
40     int server_pfd = -1;
41 nmav 1.2 int ssl_server_pfd = -1;
42 nmav 1.1
43     params->pfds = pfd1[which];
44     params->pfd_len = 0;
45    
46     while (1) {
47     int timeout;
48    
49     handle_signals( params);
50    
51     if (!params->sigterm_flag) {
52     if (params->server_s[0].socket != -1) {
53     server_pfd = params->pfd_len++;
54     params->pfds[server_pfd].fd = params->server_s[0].socket;
55     params->pfds[server_pfd].events = POLLIN | POLLPRI;
56     }
57     if (params->server_s[1].socket != -1) {
58 nmav 1.2 ssl_server_pfd = params->pfd_len++;
59     params->pfds[ssl_server_pfd].fd = params->server_s[1].socket;
60     params->pfds[ssl_server_pfd].events = POLLIN | POLLPRI;
61 nmav 1.1 }
62     }
63    
64     /* If there are any requests ready, the timeout is 0.
65     * If not, and there are any requests blocking, the
66     * timeout is ka_timeout ? ka_timeout * 1000, otherwise
67     * REQUEST_TIMEOUT * 1000.
68     * -1 means forever
69     */
70     timeout = (params->request_ready ? 0 :
71     (params->request_block ?
72     (ka_timeout ? ka_timeout * 1000 :
73     REQUEST_TIMEOUT * 1000) : -1));
74    
75     if (poll(params->pfds, params->pfd_len, timeout) == -1) {
76     if (errno == EINTR)
77     continue; /* while(1) */
78     }
79    
80     params->pfd_len = 0;
81 nmav 1.2 if (!params->sigterm_flag) {
82     if (params->pfds[server_pfd].revents & POLLIN)
83     params->server_s[0].pending_requests = 1;
84     if (params->pfds[ssl_server_pfd].revents & POLLIN)
85     params->server_s[1].pending_requests = 1;
86 nmav 1.1 }
87    
88     /* go through blocked and unblock them if possible */
89     /* also resets params->pfd_len and pfd to known blocked */
90 nmav 1.2 if (params->request_block) {
91 nmav 1.1 update_blocked(params, pfd1[other]);
92     }
93    
94     /* swap pfd */
95     params->pfds = pfd1[other];
96     temp = other;
97     other = which;
98     which = temp;
99    
100     /* process any active requests */
101     if (params->server_s[0].socket != -1) process_requests(params, &params->server_s[0]);
102     #ifdef ENABLE_SSL
103     if (params->server_s[1].socket != -1) process_requests(params, &params->server_s[1]);
104     #endif
105     }
106     }
107    
108     /*
109     * Name: update_blocked
110     *
111     * Description: iterate through the blocked requests, checking whether
112     * that file descriptor has been set by select. Update the fd_set to
113     * reflect current status.
114     *
115     * Here, we need to do some things:
116     * - keepalive timeouts simply close
117     * (this is special:: a keepalive timeout is a timeout where
118     * keepalive is active but nothing has been read yet)
119     * - regular timeouts close + error
120     * - stuff in buffer and fd ready? write it out
121     * - fd ready for other actions? do them
122     */
123    
124     void update_blocked(server_params* params, struct pollfd pfd1[])
125     {
126     request *current, *next = NULL;
127     time_t time_since;
128    
129 nmav 1.2 for (current = params->request_block; current; current = next) {
130 nmav 1.1 time_since = current_time - current->time_last;
131     next = current->next;
132    
133     // FIXME:: the first below has the chance of leaking memory!
134     // (setting status to DEAD not DONE....)
135     /* hmm, what if we are in "the middle" of a request and not
136     * just waiting for a new one... perhaps check to see if anything
137     * has been read via header position, etc... */
138     if (current->kacount < ka_max && /* we *are* in a keepalive */
139     (time_since >= ka_timeout) && /* ka timeout has passsed */
140     !current->logline) { /* haven't read anything yet */
141     current->status = DEAD; /* connection keepalive timed out */
142     ready_request( params, current);
143     continue;
144     } else if (time_since > REQUEST_TIMEOUT) {
145     log_error_doc(current);
146     fputs("connection timed out\n", stderr);
147     current->status = DEAD;
148     ready_request( params, current);
149     continue;
150     }
151    
152     if (params->pfds[current->pollfd_id].revents) {
153     ready_request( params, current);
154     } else { /* still blocked */
155     pfd1[params->pfd_len].fd = params->pfds[current->pollfd_id].fd;
156     pfd1[params->pfd_len].events = params->pfds[current->pollfd_id].events;
157     current->pollfd_id = params->pfd_len++;
158     }
159     }
160     }
161    
162     #endif /* USE_POLL */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26