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

Annotation of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (hide annotations)
Sun Oct 27 10:46:19 2002 UTC (21 years, 5 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_9, hydra_0_1_2, hydra_0_1_1, hydra_0_1_0, hydra_0_0_10
Branch point for: hydra_0_1_0_patches
Changes since 1.14: +3 -0 lines
File MIME type: text/plain
Added the ability to disable HIC threads by using 0 in the
HICThreads configuration directive.
Hydra now uses poll by default. Select is available using the --with-select
configure option.

1 nmav 1.1 /*
2     * Copyright (C) 2002 Nikos Mavroyanopoulos
3     *
4     * This file is part of BOA webserver.
5     *
6 nmav 1.7 * Hydra is free software; you can redistribute it and/or modify
7 nmav 1.1 * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11 nmav 1.7 * Hydra is distributed in the hope that it will be useful,
12 nmav 1.1 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #include "boa.h"
22 nmav 1.5 #include <signal.h> /* signal */
23 nmav 1.1
24 nmav 1.2 /* Hydra Internally handled CGIs (HIC HIC)
25     *
26     * How does it work?
27     *
28     * A special thread (maybe more than one), is used for CGIs. This tread
29     * uses one pipe to communicate with the others via hic_send_command().
30     *
31     * If a request for a HIC file arrives, the server goes as a normal CGI
32 nmav 1.5 * creates a pipe, but does not fork. It enqueues a hic_request
33     * for this (HIC) thread, and sends a SIGUSR2 signal. The HIC thread is then
34     * waken up, and handles all pending requests.
35 nmav 1.2 *
36 nmav 1.5 * The HIC thread, when receives the message, parses the CGIs,
37     * one CGI at the time, and sends the output to fd.
38 nmav 1.2 *
39     * The benefit is that in no case the server is blocked. We may have
40 nmav 1.5 * a performance problem, if the server only uses parsed CGIs.
41     *
42 nmav 1.2 */
43    
44 nmav 1.1 #ifdef ENABLE_HIC
45    
46     #include "hic.h"
47    
48 nmav 1.8 static int process_hic_request(hic_params*, hic_request * cmd);
49 nmav 1.5 void hic_dequeue(hic_request ** head, hic_request * req);
50     void hic_enqueue(hic_request ** head, hic_request * req);
51 nmav 1.1
52 nmav 1.8 void *hic_main_loop(void *_hic_params)
53 nmav 1.1 {
54 nmav 1.5 hic_request* current, *next;
55 nmav 1.8 hic_params *params = _hic_params;
56    
57 nmav 1.1 while (1) {
58 nmav 1.8 for (current = params->request_head;current;current=next) {
59 nmav 1.1
60 nmav 1.5 #ifdef ENABLE_SMP
61 nmav 1.8 pthread_mutex_lock(&params->lock);
62 nmav 1.5 #endif
63     next = current->next;
64     #ifdef ENABLE_SMP
65 nmav 1.8 pthread_mutex_unlock(&params->lock);
66 nmav 1.5 #endif
67 nmav 1.1
68 nmav 1.8 if (process_hic_request( params, current) == -1) {
69 nmav 1.1 log_error_time();
70     fprintf(stderr, "hic: Error while processing command.\n");
71     exit(1);
72     }
73     }
74 nmav 1.5
75     /* If somebody sends a command, then he should
76     * send a sigusr2 as well.
77     */
78 nmav 1.6 unblock_sigusr2();
79 nmav 1.8 if (!params->request_head) pause();
80 nmav 1.6 block_sigusr2();
81 nmav 1.5
82 nmav 1.8 if (params->sigchld_flag)
83 nmav 1.5 sigchld_run();
84 nmav 1.12 if (params->sighup_flag)
85     sighup_run();
86 nmav 1.5
87 nmav 1.1
88     }
89    
90     }
91    
92 nmav 1.8 static int process_hic_request(hic_params* params, hic_request * req)
93 nmav 1.1 {
94 nmav 1.5 hic_module_st *hst;
95     hic_stuff* cmd = &req->command;
96    
97     #ifdef ENABLE_SMP
98 nmav 1.8 pthread_mutex_lock(&params->lock);
99 nmav 1.5 #endif
100 nmav 1.8 hic_dequeue( &params->request_head, req);
101 nmav 1.5 #ifdef ENABLE_SMP
102 nmav 1.8 pthread_mutex_unlock(&params->lock);
103 nmav 1.5 #endif
104 nmav 1.3
105 nmav 1.5 hst = find_hic_appr_module(get_mime_type(cmd->path_translated), 0);
106 nmav 1.3 if (hst == NULL) {
107     log_error_time();
108 nmav 1.5 fprintf(stderr, "Could not find HIC handler for '%s'\n",
109     cmd->path_translated);
110     close(cmd->out_fd);
111     free( req);
112 nmav 1.3 return 0;
113     }
114    
115 nmav 1.5 hst->request(cmd);
116     close(cmd->out_fd);
117     free( req);
118 nmav 1.1
119 nmav 1.3 /*
120 nmav 1.1 log_error_time();
121     fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
122 nmav 1.3 */
123 nmav 1.1
124     return 0;
125     }
126    
127 nmav 1.8 #ifdef ENABLE_SMP
128     /* We use this index, to send messages to different
129     * HIC thread every time.
130     */
131 nmav 1.13 static pthread_mutex_t hic_index_lock = PTHREAD_MUTEX_INITIALIZER;
132     static int hic_index;
133 nmav 1.8 #endif
134    
135 nmav 1.5 /* Sends a command to a HIC thread.
136     */
137     int hic_send_command(request * req, int out_fd)
138 nmav 1.1 {
139 nmav 1.5 hic_request *x;
140 nmav 1.8 hic_params *params;
141    
142 nmav 1.15 if (global_hic_params_size == 0) /* hic is disabled */
143     return -1;
144    
145 nmav 1.8 /* choose a random hic thread */
146     if (global_hic_params_size > 1) {
147     #ifdef ENABLE_SMP
148 nmav 1.13 pthread_mutex_lock( &hic_index_lock);
149 nmav 1.8 #endif
150 nmav 1.13 params = &global_hic_params[ hic_index];
151     hic_index++;
152     hic_index %= global_hic_params_size;
153 nmav 1.8 #ifdef ENABLE_SMP
154 nmav 1.13 pthread_mutex_unlock( &hic_index_lock);
155 nmav 1.8 #endif
156     } else {
157     params = &global_hic_params[0];
158     }
159 nmav 1.1
160 nmav 1.5 x = malloc( sizeof( hic_request));
161     if (x==NULL)
162     return -1;
163    
164     x->next = x->prev = NULL;
165     x->command.cgi_env = req->cgi_env;
166     x->command.one_one = 0;
167 nmav 1.14 x->command.post_data_fd = req->post_data_fd.fds[0];
168 nmav 1.5 x->command.out_fd = out_fd;
169     x->command.path_translated = req->path_translated;
170 nmav 1.1
171     #ifdef ENABLE_SMP
172 nmav 1.8 pthread_mutex_lock(&params->lock);
173 nmav 1.1 #endif
174 nmav 1.5
175 nmav 1.8 hic_enqueue( &params->request_head, x);
176 nmav 1.1 #ifdef ENABLE_SMP
177 nmav 1.8 /* Notify the HIC thread about the pending request
178     */
179     pthread_kill( params->tid, SIGUSR2);
180 nmav 1.1 #endif
181    
182     #ifdef ENABLE_SMP
183 nmav 1.8 pthread_mutex_unlock(&params->lock);
184 nmav 1.1 #endif
185    
186 nmav 1.5 return 1;
187 nmav 1.1
188     }
189    
190 nmav 1.5 /* Implement a basic queue for HIC stuff. This is created after
191     * queue.c.
192     */
193 nmav 1.1
194 nmav 1.5 #include "queue.h"
195 nmav 1.1
196 nmav 1.5 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
197     DEQUEUE_FUNCTION( hic_dequeue, hic_request)
198 nmav 1.1
199 nmav 1.5 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26