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

Contents of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (show 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 /*
2 * Copyright (C) 2002 Nikos Mavroyanopoulos
3 *
4 * This file is part of BOA webserver.
5 *
6 * Hydra is free software; you can redistribute it and/or modify
7 * 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 * Hydra is distributed in the hope that it will be useful,
12 * 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 #include <signal.h> /* signal */
23
24 /* 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 * 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 *
36 * The HIC thread, when receives the message, parses the CGIs,
37 * one CGI at the time, and sends the output to fd.
38 *
39 * The benefit is that in no case the server is blocked. We may have
40 * a performance problem, if the server only uses parsed CGIs.
41 *
42 */
43
44 #ifdef ENABLE_HIC
45
46 #include "hic.h"
47
48 static int process_hic_request(hic_params*, hic_request * cmd);
49 void hic_dequeue(hic_request ** head, hic_request * req);
50 void hic_enqueue(hic_request ** head, hic_request * req);
51
52 void *hic_main_loop(void *_hic_params)
53 {
54 hic_request* current, *next;
55 hic_params *params = _hic_params;
56
57 while (1) {
58 for (current = params->request_head;current;current=next) {
59
60 #ifdef ENABLE_SMP
61 pthread_mutex_lock(&params->lock);
62 #endif
63 next = current->next;
64 #ifdef ENABLE_SMP
65 pthread_mutex_unlock(&params->lock);
66 #endif
67
68 if (process_hic_request( params, current) == -1) {
69 log_error_time();
70 fprintf(stderr, "hic: Error while processing command.\n");
71 exit(1);
72 }
73 }
74
75 /* If somebody sends a command, then he should
76 * send a sigusr2 as well.
77 */
78 unblock_sigusr2();
79 if (!params->request_head) pause();
80 block_sigusr2();
81
82 if (params->sigchld_flag)
83 sigchld_run();
84 if (params->sighup_flag)
85 sighup_run();
86
87
88 }
89
90 }
91
92 static int process_hic_request(hic_params* params, hic_request * req)
93 {
94 hic_module_st *hst;
95 hic_stuff* cmd = &req->command;
96
97 #ifdef ENABLE_SMP
98 pthread_mutex_lock(&params->lock);
99 #endif
100 hic_dequeue( &params->request_head, req);
101 #ifdef ENABLE_SMP
102 pthread_mutex_unlock(&params->lock);
103 #endif
104
105 hst = find_hic_appr_module(get_mime_type(cmd->path_translated), 0);
106 if (hst == NULL) {
107 log_error_time();
108 fprintf(stderr, "Could not find HIC handler for '%s'\n",
109 cmd->path_translated);
110 close(cmd->out_fd);
111 free( req);
112 return 0;
113 }
114
115 hst->request(cmd);
116 close(cmd->out_fd);
117 free( req);
118
119 /*
120 log_error_time();
121 fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
122 */
123
124 return 0;
125 }
126
127 #ifdef ENABLE_SMP
128 /* We use this index, to send messages to different
129 * HIC thread every time.
130 */
131 static pthread_mutex_t hic_index_lock = PTHREAD_MUTEX_INITIALIZER;
132 static int hic_index;
133 #endif
134
135 /* Sends a command to a HIC thread.
136 */
137 int hic_send_command(request * req, int out_fd)
138 {
139 hic_request *x;
140 hic_params *params;
141
142 if (global_hic_params_size == 0) /* hic is disabled */
143 return -1;
144
145 /* choose a random hic thread */
146 if (global_hic_params_size > 1) {
147 #ifdef ENABLE_SMP
148 pthread_mutex_lock( &hic_index_lock);
149 #endif
150 params = &global_hic_params[ hic_index];
151 hic_index++;
152 hic_index %= global_hic_params_size;
153 #ifdef ENABLE_SMP
154 pthread_mutex_unlock( &hic_index_lock);
155 #endif
156 } else {
157 params = &global_hic_params[0];
158 }
159
160 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 x->command.post_data_fd = req->post_data_fd.fds[0];
168 x->command.out_fd = out_fd;
169 x->command.path_translated = req->path_translated;
170
171 #ifdef ENABLE_SMP
172 pthread_mutex_lock(&params->lock);
173 #endif
174
175 hic_enqueue( &params->request_head, x);
176 #ifdef ENABLE_SMP
177 /* Notify the HIC thread about the pending request
178 */
179 pthread_kill( params->tid, SIGUSR2);
180 #endif
181
182 #ifdef ENABLE_SMP
183 pthread_mutex_unlock(&params->lock);
184 #endif
185
186 return 1;
187
188 }
189
190 /* Implement a basic queue for HIC stuff. This is created after
191 * queue.c.
192 */
193
194 #include "queue.h"
195
196 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
197 DEQUEUE_FUNCTION( hic_dequeue, hic_request)
198
199 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26