2
* Copyright 1999-2004 The Apache Software Foundation
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
/***************************************************************************
18
* Description: Workers controller *
19
* Author: Gal Shachor <shachor@il.ibm.com> *
20
* Author: Henri Gomez <hgomez@apache.org> *
21
* Version: $Revision: 1.36 $ *
22
***************************************************************************/
24
#define _PLACE_WORKER_LIST_HERE
25
#include "jk_worker_list.h"
26
#include "jk_worker.h"
30
static void close_workers(jk_logger_t *l);
32
static worker_factory get_factory_for(const char *type);
34
static int build_worker_map(jk_map_t *init_data,
36
unsigned num_of_workers,
37
jk_worker_env_t *we, jk_logger_t *l);
39
/* Global worker list */
40
static jk_map_t *worker_map;
42
static JK_CRIT_SEC worker_lock;
44
static int worker_maintain_time = 0;
46
int wc_open(jk_map_t *init_data, jk_worker_env_t *we, jk_logger_t *l)
51
if (!jk_map_alloc(&worker_map)) {
55
JK_INIT_CS(&worker_lock, rc);
57
jk_log(l, JK_LOG_ERROR,
58
"creating thread lock errno=%d",
64
if (!jk_get_worker_list(init_data, &(we->worker_list),
65
&we->num_of_workers)) {
67
we->num_of_workers = 0;
68
we->worker_list = NULL;
72
worker_maintain_time = jk_get_worker_maintain_time(init_data);
74
if (!build_worker_map(init_data, we->worker_list,
75
we->num_of_workers, we, l)) {
77
we->num_of_workers = 0;
78
we->worker_list = NULL;
88
void wc_close(jk_logger_t *l)
92
JK_DELETE_CS(&worker_lock, rc);
97
jk_worker_t *wc_get_worker_for_name(const char *name, jk_logger_t *l)
103
JK_LOG_NULL_PARAMS(l);
108
rc = jk_map_get(worker_map, name, NULL);
110
if (JK_IS_DEBUG_LEVEL(l))
111
jk_log(l, JK_LOG_DEBUG, "%s a worker %s",
112
rc ? "found" : "did not find", name);
117
int wc_create_worker(const char *name, int use_map,
119
jk_worker_t **rc, jk_worker_env_t *we, jk_logger_t *l)
124
const char *type = jk_get_worker_type(init_data, name);
125
worker_factory fac = get_factory_for(type);
126
jk_worker_t *w = NULL;
127
unsigned int i, num_of_maps;
134
jk_log(l, JK_LOG_ERROR, "Unknown worker type %s for worker %s",
140
if (JK_IS_DEBUG_LEVEL(l))
141
jk_log(l, JK_LOG_DEBUG,
142
"about to create instance %s of %s", name,
145
if (((wtype = fac(&w, name, l)) == 0) || !w) {
146
jk_log(l, JK_LOG_ERROR,
147
"factory for %s failed for %s", type,
153
if (JK_IS_DEBUG_LEVEL(l))
154
jk_log(l, JK_LOG_DEBUG,
155
"about to validate and init %s", name);
156
if (!w->validate(w, init_data, we, l)) {
158
jk_log(l, JK_LOG_ERROR,
159
"validate failed for %s", name);
164
if (!w->init(w, init_data, we, l)) {
166
jk_log(l, JK_LOG_ERROR, "init failed for %s",
172
jk_get_worker_mount_list(init_data, name,
174
&num_of_maps) && num_of_maps) {
175
for (i = 0; i < num_of_maps; i++) {
176
if (JK_IS_DEBUG_LEVEL(l))
177
jk_log(l, JK_LOG_DEBUG,
178
"mounting %s to worker %s",
180
if (uri_worker_map_add(we->uri_to_worker, map_names[i],
181
name, l) == JK_FALSE) {
183
jk_log(l, JK_LOG_ERROR,
184
"validate failed for %s", name);
196
JK_LOG_NULL_PARAMS(l);
200
static void close_workers(jk_logger_t *l)
202
int sz = jk_map_size(worker_map);
208
for (i = 0; i < sz; i++) {
209
jk_worker_t *w = jk_map_value_at(worker_map, i);
211
if (JK_IS_DEBUG_LEVEL(l))
212
jk_log(l, JK_LOG_DEBUG,
213
"close_workers will destroy worker %s",
214
jk_map_name_at(worker_map, i));
219
jk_map_free(&worker_map);
223
static int build_worker_map(jk_map_t *init_data,
225
unsigned num_of_workers,
226
jk_worker_env_t *we, jk_logger_t *l)
232
for (i = 0; i < num_of_workers; i++) {
233
jk_worker_t *w = NULL;
235
if (JK_IS_DEBUG_LEVEL(l))
236
jk_log(l, JK_LOG_DEBUG,
237
"creating worker %s", worker_list[i]);
239
if (wc_create_worker(worker_list[i], 1, init_data, &w, we, l)) {
240
jk_worker_t *oldw = NULL;
241
if (!jk_map_put(worker_map, worker_list[i], w, (void *)&oldw)) {
247
if (JK_IS_DEBUG_LEVEL(l))
248
jk_log(l, JK_LOG_DEBUG,
249
"removing old %s worker",
252
oldw->destroy(&oldw, l);
256
jk_log(l, JK_LOG_ERROR,
257
"failed to create worker %s",
268
static worker_factory get_factory_for(const char *type)
270
worker_factory_record_t *factory = &worker_factories[0];
271
while (factory->name) {
272
if (0 == strcmp(factory->name, type)) {
282
void wc_maintain(jk_logger_t *l)
284
static time_t last_maintain = 0;
285
int sz = jk_map_size(worker_map);
289
if (sz > 0 && worker_maintain_time > 0) {
292
JK_ENTER_CS(&worker_lock, i);
294
if (difftime(now, last_maintain) >= worker_maintain_time) {
296
JK_LEAVE_CS(&worker_lock, i);
297
for (i = 0; i < sz; i++) {
298
jk_worker_t *w = jk_map_value_at(worker_map, i);
299
if (w && w->maintain) {
300
if (JK_IS_DEBUG_LEVEL(l))
301
jk_log(l, JK_LOG_DEBUG,
302
"Maintaining worker %s",
303
jk_map_name_at(worker_map, i));
309
JK_LEAVE_CS(&worker_lock, i);