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

Annotation of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.16 - (hide annotations)
Wed Jan 22 07:51:50 2003 UTC (21 years, 2 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_7, hydra_0_1_6, hydra_0_1_4
Changes since 1.15: +4 -3 lines
File MIME type: text/plain
merged changes from 0.1.x branch.

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 nmav 1.1
118 nmav 1.3 /*
119 nmav 1.1 log_error_time();
120     fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
121 nmav 1.16 */
122    
123     free( req);
124 nmav 1.1
125     return 0;
126     }
127    
128 nmav 1.8 #ifdef ENABLE_SMP
129     /* We use this index, to send messages to different
130     * HIC thread every time.
131     */
132 nmav 1.13 static pthread_mutex_t hic_index_lock = PTHREAD_MUTEX_INITIALIZER;
133     static int hic_index;
134 nmav 1.8 #endif
135    
136 nmav 1.5 /* Sends a command to a HIC thread.
137     */
138     int hic_send_command(request * req, int out_fd)
139 nmav 1.1 {
140 nmav 1.5 hic_request *x;
141 nmav 1.8 hic_params *params;
142    
143 nmav 1.15 if (global_hic_params_size == 0) /* hic is disabled */
144     return -1;
145    
146 nmav 1.8 /* choose a random hic thread */
147     if (global_hic_params_size > 1) {
148     #ifdef ENABLE_SMP
149 nmav 1.13 pthread_mutex_lock( &hic_index_lock);
150 nmav 1.8 #endif
151 nmav 1.13 params = &global_hic_params[ hic_index];
152     hic_index++;
153     hic_index %= global_hic_params_size;
154 nmav 1.8 #ifdef ENABLE_SMP
155 nmav 1.13 pthread_mutex_unlock( &hic_index_lock);
156 nmav 1.8 #endif
157     } else {
158     params = &global_hic_params[0];
159     }
160 nmav 1.1
161 nmav 1.5 x = malloc( sizeof( hic_request));
162     if (x==NULL)
163     return -1;
164    
165     x->next = x->prev = NULL;
166     x->command.cgi_env = req->cgi_env;
167 nmav 1.16 x->command.http_version = req->http_version;
168 nmav 1.14 x->command.post_data_fd = req->post_data_fd.fds[0];
169 nmav 1.5 x->command.out_fd = out_fd;
170     x->command.path_translated = req->path_translated;
171 nmav 1.1
172     #ifdef ENABLE_SMP
173 nmav 1.8 pthread_mutex_lock(&params->lock);
174 nmav 1.1 #endif
175 nmav 1.5
176 nmav 1.8 hic_enqueue( &params->request_head, x);
177 nmav 1.1 #ifdef ENABLE_SMP
178 nmav 1.8 /* Notify the HIC thread about the pending request
179     */
180     pthread_kill( params->tid, SIGUSR2);
181 nmav 1.1 #endif
182    
183     #ifdef ENABLE_SMP
184 nmav 1.8 pthread_mutex_unlock(&params->lock);
185 nmav 1.1 #endif
186    
187 nmav 1.5 return 1;
188 nmav 1.1
189     }
190    
191 nmav 1.5 /* Implement a basic queue for HIC stuff. This is created after
192     * queue.c.
193     */
194 nmav 1.1
195 nmav 1.5 #include "queue.h"
196 nmav 1.1
197 nmav 1.5 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
198     DEQUEUE_FUNCTION( hic_dequeue, hic_request)
199 nmav 1.1
200 nmav 1.5 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26