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

Contents of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations)
Wed Oct 9 08:49:46 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_7
Changes since 1.11: +2 -7 lines
File MIME type: text/plain
Improved the thread killing mechanism, to avoid unexpected errors. Now childen threads are killed with a HUP signal instead of pthread_cancel().

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 index_lock = PTHREAD_MUTEX_INITIALIZER;
132 static int 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 /* choose a random hic thread */
143 if (global_hic_params_size > 1) {
144 #ifdef ENABLE_SMP
145 pthread_mutex_lock( &index_lock);
146 #endif
147 params = &global_hic_params[ index];
148 index++;
149 index %= global_hic_params_size;
150 #ifdef ENABLE_SMP
151 pthread_mutex_unlock( &index_lock);
152 #endif
153 } else {
154 params = &global_hic_params[0];
155 }
156
157 x = malloc( sizeof( hic_request));
158 if (x==NULL)
159 return -1;
160
161 x->next = x->prev = NULL;
162 x->command.cgi_env = req->cgi_env;
163 x->command.one_one = 0;
164 x->command.post_data_fd = req->post_data_fd;
165 x->command.out_fd = out_fd;
166 x->command.path_translated = req->path_translated;
167
168 #ifdef ENABLE_SMP
169 pthread_mutex_lock(&params->lock);
170 #endif
171
172 hic_enqueue( &params->request_head, x);
173 #ifdef ENABLE_SMP
174 /* Notify the HIC thread about the pending request
175 */
176 pthread_kill( params->tid, SIGUSR2);
177 #endif
178
179 #ifdef ENABLE_SMP
180 pthread_mutex_unlock(&params->lock);
181 #endif
182
183 return 1;
184
185 }
186
187 /* Implement a basic queue for HIC stuff. This is created after
188 * queue.c.
189 */
190
191 #include "queue.h"
192
193 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
194 DEQUEUE_FUNCTION( hic_dequeue, hic_request)
195
196 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26