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

Contents of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Sat Sep 28 16:32:37 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_3
Changes since 1.6: +2 -2 lines
File MIME type: text/plain
In sighup and sigterm, the HIC thread is terminated as well.

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 #ifdef ENABLE_SMP
49 pthread_mutex_t hic_lock = PTHREAD_MUTEX_INITIALIZER;
50 #endif
51
52 typedef struct _hic_request {
53 struct _hic_request *next;
54 struct _hic_request *prev;
55 hic_stuff command;
56 } hic_request;
57
58 hic_request * hic_request_head = NULL;
59
60 static int process_hic_request(hic_request * cmd);
61 void hic_dequeue(hic_request ** head, hic_request * req);
62 void hic_enqueue(hic_request ** head, hic_request * req);
63 int hic_sigchld_flag = 0; /* if we received a SIGCHLD signal, then this flag
64 * is non zero */
65
66 void *hic_main_loop(void *cml)
67 {
68 hic_request* current, *next;
69
70 while (1) {
71 for (current = hic_request_head;current;current=next) {
72
73 #ifdef ENABLE_SMP
74 pthread_mutex_lock(&hic_lock);
75 #endif
76 next = current->next;
77 #ifdef ENABLE_SMP
78 pthread_mutex_unlock(&hic_lock);
79 #endif
80
81 if (process_hic_request( current) == -1) {
82 log_error_time();
83 fprintf(stderr, "hic: Error while processing command.\n");
84 exit(1);
85 }
86 }
87
88 /* If somebody sends a command, then he should
89 * send a sigusr2 as well.
90 */
91 unblock_sigusr2();
92 if (!hic_request_head) pause();
93 block_sigusr2();
94
95 if (hic_sigchld_flag)
96 sigchld_run();
97
98
99 }
100
101 }
102
103 static int process_hic_request(hic_request * req)
104 {
105 hic_module_st *hst;
106 hic_stuff* cmd = &req->command;
107
108 #ifdef ENABLE_SMP
109 pthread_mutex_lock(&hic_lock);
110 #endif
111 hic_dequeue( &hic_request_head, req);
112 #ifdef ENABLE_SMP
113 pthread_mutex_unlock(&hic_lock);
114 #endif
115
116 hst = find_hic_appr_module(get_mime_type(cmd->path_translated), 0);
117 if (hst == NULL) {
118 log_error_time();
119 fprintf(stderr, "Could not find HIC handler for '%s'\n",
120 cmd->path_translated);
121 close(cmd->out_fd);
122 free( req);
123 return 0;
124 }
125
126 hst->request(cmd);
127 close(cmd->out_fd);
128 free( req);
129
130 /*
131 log_error_time();
132 fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
133 */
134
135 return 0;
136 }
137
138 /* Sends a command to a HIC thread.
139 */
140 int hic_send_command(request * req, int out_fd)
141 {
142 hic_request *x;
143
144 x = malloc( sizeof( hic_request));
145 if (x==NULL)
146 return -1;
147
148 x->next = x->prev = NULL;
149 x->command.cgi_env = req->cgi_env;
150 x->command.cgi_env_max = req->cgi_env_index;
151 x->command.one_one = 0;
152 x->command.post_data_fd = req->post_data_fd;
153 x->command.out_fd = out_fd;
154 x->command.request_uri = req->request_uri;
155 x->command.path_translated = req->path_translated;
156
157 #ifdef ENABLE_SMP
158 pthread_mutex_lock(&hic_lock);
159 #endif
160
161 hic_enqueue( &hic_request_head, x);
162 #ifdef ENABLE_SMP
163 /* Notify the main loop */
164 pthread_kill( hic_tid, SIGUSR2);
165 #endif
166
167 #ifdef ENABLE_SMP
168 pthread_mutex_unlock(&hic_lock);
169 #endif
170
171 return 1;
172
173 }
174
175 /* Implement a basic queue for HIC stuff. This is created after
176 * queue.c.
177 */
178
179 #include "queue.h"
180
181 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
182 DEQUEUE_FUNCTION( hic_dequeue, hic_request)
183
184 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26