Lines 25-31
Link Here
|
25 |
|
25 |
|
26 |
#include "httpd.h" |
26 |
#include "httpd.h" |
27 |
#include "http_main.h" |
27 |
#include "http_main.h" |
28 |
#include "http_core.h" |
28 |
#include "ap_mpm.h" /* for ap_mpm_query() */ |
29 |
|
29 |
|
30 |
#define AP_SLOTMEM_IS_PREGRAB(t) (t->desc->type & AP_SLOTMEM_TYPE_PREGRAB) |
30 |
#define AP_SLOTMEM_IS_PREGRAB(t) (t->desc->type & AP_SLOTMEM_TYPE_PREGRAB) |
31 |
#define AP_SLOTMEM_IS_PERSIST(t) (t->desc->type & AP_SLOTMEM_TYPE_PERSIST) |
31 |
#define AP_SLOTMEM_IS_PERSIST(t) (t->desc->type & AP_SLOTMEM_TYPE_PERSIST) |
Lines 47-53
struct ap_slotmem_instance_t {
Link Here
|
47 |
int fbased; /* filebased? */ |
47 |
int fbased; /* filebased? */ |
48 |
void *shm; /* ptr to memory segment (apr_shm_t *) */ |
48 |
void *shm; /* ptr to memory segment (apr_shm_t *) */ |
49 |
void *base; /* data set start */ |
49 |
void *base; /* data set start */ |
50 |
apr_pool_t *pool; /* per segment pool (generation cleared) */ |
50 |
apr_pool_t *gpool; /* per segment pool (generation cleared) */ |
51 |
char *inuse; /* in-use flag table*/ |
51 |
char *inuse; /* in-use flag table*/ |
52 |
unsigned int *num_free; /* slot free count for this instance */ |
52 |
unsigned int *num_free; /* slot free count for this instance */ |
53 |
void *persist; /* persist dataset start */ |
53 |
void *persist; /* persist dataset start */ |
Lines 68-77
struct ap_slotmem_instance_t {
Link Here
|
68 |
* |_____________________ File (mem->persist + [meta]) __| |
68 |
* |_____________________ File (mem->persist + [meta]) __| |
69 |
*/ |
69 |
*/ |
70 |
|
70 |
|
71 |
|
|
|
72 |
/* global pool and list of slotmem we are handling */ |
71 |
/* global pool and list of slotmem we are handling */ |
73 |
static struct ap_slotmem_instance_t *globallistmem = NULL, |
72 |
static struct ap_slotmem_instance_t *globallistmem = NULL; |
74 |
**retained_globallistmem = NULL; |
|
|
75 |
static apr_pool_t *gpool = NULL; |
73 |
static apr_pool_t *gpool = NULL; |
76 |
|
74 |
|
77 |
#define DEFAULT_SLOTMEM_PREFIX "slotmem-shm-" |
75 |
#define DEFAULT_SLOTMEM_PREFIX "slotmem-shm-" |
Lines 95-103
static int slotmem_filenames(apr_pool_t *pool,
Link Here
|
95 |
|
93 |
|
96 |
if (slotname && *slotname && strcasecmp(slotname, "none") != 0) { |
94 |
if (slotname && *slotname && strcasecmp(slotname, "none") != 0) { |
97 |
if (slotname[0] != '/') { |
95 |
if (slotname[0] != '/') { |
98 |
fname = apr_pstrcat(pool, DEFAULT_SLOTMEM_PREFIX, |
96 |
/* Each generation needs its own file name. */ |
99 |
slotname, DEFAULT_SLOTMEM_SUFFIX, |
97 |
int generation = 0; |
100 |
NULL); |
98 |
ap_mpm_query(AP_MPMQ_GENERATION, &generation); |
|
|
99 |
fname = apr_psprintf(pool, "%s%s_%x%s", DEFAULT_SLOTMEM_PREFIX, |
100 |
slotname, generation, DEFAULT_SLOTMEM_SUFFIX); |
101 |
fname = ap_runtime_dir_relative(pool, fname); |
101 |
fname = ap_runtime_dir_relative(pool, fname); |
102 |
} |
102 |
} |
103 |
else { |
103 |
else { |
Lines 108-116
static int slotmem_filenames(apr_pool_t *pool,
Link Here
|
108 |
} |
108 |
} |
109 |
|
109 |
|
110 |
if (persistname) { |
110 |
if (persistname) { |
111 |
pname = apr_pstrcat(pool, fname, |
111 |
/* Persisted file names are immutable... */ |
112 |
DEFAULT_SLOTMEM_PERSIST_SUFFIX, |
112 |
if (slotname[0] != '/') { |
113 |
NULL); |
113 |
pname = apr_pstrcat(pool, DEFAULT_SLOTMEM_PREFIX, |
|
|
114 |
slotname, DEFAULT_SLOTMEM_SUFFIX, |
115 |
DEFAULT_SLOTMEM_PERSIST_SUFFIX, |
116 |
NULL); |
117 |
pname = ap_runtime_dir_relative(pool, pname); |
118 |
} |
119 |
else { |
120 |
pname = apr_pstrcat(pool, slotname, |
121 |
DEFAULT_SLOTMEM_PERSIST_SUFFIX, |
122 |
NULL); |
123 |
} |
114 |
} |
124 |
} |
115 |
} |
125 |
} |
116 |
|
126 |
|
Lines 153-163
static void store_slotmem(ap_slotmem_instance_t *s
Link Here
|
153 |
|
163 |
|
154 |
if (storename) { |
164 |
if (storename) { |
155 |
rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, |
165 |
rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, |
156 |
APR_OS_DEFAULT, slotmem->pool); |
166 |
APR_OS_DEFAULT, slotmem->gpool); |
157 |
if (APR_STATUS_IS_EEXIST(rv)) { |
167 |
if (APR_STATUS_IS_EEXIST(rv)) { |
158 |
apr_file_remove(storename, slotmem->pool); |
168 |
apr_file_remove(storename, slotmem->gpool); |
159 |
rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, |
169 |
rv = apr_file_open(&fp, storename, APR_CREATE | APR_READ | APR_WRITE, |
160 |
APR_OS_DEFAULT, slotmem->pool); |
170 |
APR_OS_DEFAULT, slotmem->gpool); |
161 |
} |
171 |
} |
162 |
if (rv != APR_SUCCESS) { |
172 |
if (rv != APR_SUCCESS) { |
163 |
return; |
173 |
return; |
Lines 178-184
static void store_slotmem(ap_slotmem_instance_t *s
Link Here
|
178 |
} |
188 |
} |
179 |
apr_file_close(fp); |
189 |
apr_file_close(fp); |
180 |
if (rv != APR_SUCCESS) { |
190 |
if (rv != APR_SUCCESS) { |
181 |
apr_file_remove(storename, slotmem->pool); |
191 |
apr_file_remove(storename, slotmem->gpool); |
182 |
} |
192 |
} |
183 |
} |
193 |
} |
184 |
} |
194 |
} |
Lines 191-197
static apr_status_t restore_slotmem(sharedslotdesc
Link Here
|
191 |
apr_status_t rv = APR_ENOTIMPL; |
201 |
apr_status_t rv = APR_ENOTIMPL; |
192 |
void *ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
202 |
void *ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
193 |
apr_size_t dsize = size - AP_SLOTMEM_OFFSET; |
203 |
apr_size_t dsize = size - AP_SLOTMEM_OFFSET; |
194 |
apr_size_t nbytes = dsize; |
|
|
195 |
unsigned char digest[APR_MD5_DIGESTSIZE]; |
204 |
unsigned char digest[APR_MD5_DIGESTSIZE]; |
196 |
unsigned char digest2[APR_MD5_DIGESTSIZE]; |
205 |
unsigned char digest2[APR_MD5_DIGESTSIZE]; |
197 |
char desc_buf[AP_SLOTMEM_OFFSET]; |
206 |
char desc_buf[AP_SLOTMEM_OFFSET]; |
Lines 203-210
static apr_status_t restore_slotmem(sharedslotdesc
Link Here
|
203 |
rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT, |
212 |
rv = apr_file_open(&fp, storename, APR_READ | APR_WRITE, APR_OS_DEFAULT, |
204 |
pool); |
213 |
pool); |
205 |
if (rv == APR_SUCCESS) { |
214 |
if (rv == APR_SUCCESS) { |
206 |
rv = apr_file_read(fp, ptr, &nbytes); |
215 |
rv = apr_file_read_full(fp, ptr, dsize, NULL); |
207 |
if ((rv == APR_SUCCESS || rv == APR_EOF) && nbytes == dsize) { |
216 |
if (rv == APR_SUCCESS || rv == APR_EOF) { |
208 |
rv = APR_SUCCESS; /* for successful return @ EOF */ |
217 |
rv = APR_SUCCESS; /* for successful return @ EOF */ |
209 |
/* |
218 |
/* |
210 |
* if at EOF, don't bother checking md5 |
219 |
* if at EOF, don't bother checking md5 |
Lines 211-221
static apr_status_t restore_slotmem(sharedslotdesc
Link Here
|
211 |
* - backwards compatibility |
220 |
* - backwards compatibility |
212 |
* */ |
221 |
* */ |
213 |
if (apr_file_eof(fp) != APR_EOF) { |
222 |
if (apr_file_eof(fp) != APR_EOF) { |
214 |
apr_size_t ds = APR_MD5_DIGESTSIZE; |
223 |
rv = apr_file_read_full(fp, digest, APR_MD5_DIGESTSIZE, NULL); |
215 |
rv = apr_file_read(fp, digest, &ds); |
224 |
if (rv == APR_SUCCESS || rv == APR_EOF) { |
216 |
if ((rv == APR_SUCCESS || rv == APR_EOF) |
225 |
apr_md5(digest2, ptr, APR_MD5_DIGESTSIZE); |
217 |
&& ds == APR_MD5_DIGESTSIZE) { |
|
|
218 |
apr_md5(digest2, ptr, nbytes); |
219 |
if (memcmp(digest, digest2, APR_MD5_DIGESTSIZE)) { |
226 |
if (memcmp(digest, digest2, APR_MD5_DIGESTSIZE)) { |
220 |
rv = APR_EMISMATCH; |
227 |
rv = APR_EMISMATCH; |
221 |
} |
228 |
} |
Lines 224-234
static apr_status_t restore_slotmem(sharedslotdesc
Link Here
|
224 |
* - backwards compatibility |
231 |
* - backwards compatibility |
225 |
* */ |
232 |
* */ |
226 |
else if (apr_file_eof(fp) != APR_EOF) { |
233 |
else if (apr_file_eof(fp) != APR_EOF) { |
227 |
nbytes = sizeof(desc_buf); |
234 |
rv = apr_file_read_full(fp, desc_buf, sizeof(desc_buf), NULL); |
228 |
rv = apr_file_read(fp, desc_buf, &nbytes); |
235 |
if (rv == APR_SUCCESS || rv == APR_EOF) { |
229 |
if ((rv == APR_SUCCESS || rv == APR_EOF) |
236 |
if (memcmp(desc, desc_buf, sizeof(desc_buf))) { |
230 |
&& nbytes == sizeof(desc_buf)) { |
|
|
231 |
if (memcmp(desc, desc_buf, nbytes)) { |
232 |
rv = APR_EMISMATCH; |
237 |
rv = APR_EMISMATCH; |
233 |
} |
238 |
} |
234 |
else { |
239 |
else { |
Lines 287-337
static APR_INLINE int is_child_process(void)
Link Here
|
287 |
#endif |
292 |
#endif |
288 |
} |
293 |
} |
289 |
|
294 |
|
290 |
static apr_status_t cleanup_slotmem(void *is_startup) |
295 |
static apr_status_t cleanup_slotmem(void *param) |
291 |
{ |
296 |
{ |
292 |
int is_exiting = (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_EXITING); |
297 |
int is_child = is_child_process(); |
293 |
ap_slotmem_instance_t *mem; |
298 |
ap_slotmem_instance_t *next = globallistmem; |
294 |
|
299 |
|
295 |
if (is_child_process()) { |
300 |
while (next) { |
296 |
/* No reuse/retained data from here, let pconf cleanup everything */ |
301 |
if (!is_child && AP_SLOTMEM_IS_PERSIST(next)) { |
297 |
*retained_globallistmem = globallistmem = NULL; |
302 |
store_slotmem(next); |
298 |
return APR_SUCCESS; |
|
|
299 |
} |
300 |
|
301 |
/* When in startup/pre-config's cleanup, the retained data and global pool |
302 |
* are not used yet, but the SHMs contents were untouched hence they don't |
303 |
* need to be persisted, simply unlink them. |
304 |
* Otherwise when restarting or stopping we want to flush persisted data, |
305 |
* and in the stopping/exiting case we also want to unlink the SHMs. |
306 |
*/ |
307 |
for (mem = globallistmem; mem; mem = mem->next) { |
308 |
int unlink; |
309 |
if (is_startup) { |
310 |
unlink = mem->fbased; |
311 |
} |
303 |
} |
312 |
else { |
304 |
apr_shm_destroy(next->shm); |
313 |
if (AP_SLOTMEM_IS_PERSIST(mem)) { |
305 |
apr_shm_remove(next->name, next->gpool); |
314 |
store_slotmem(mem); |
306 |
next = next->next; |
315 |
} |
|
|
316 |
unlink = is_exiting; |
317 |
} |
318 |
if (unlink) { |
319 |
/* Some systems may require the descriptor to be closed before |
320 |
* unlink, thus call destroy() first. |
321 |
*/ |
322 |
apr_shm_destroy(mem->shm); |
323 |
apr_shm_remove(mem->name, mem->pool); |
324 |
} |
325 |
} |
307 |
} |
326 |
|
308 |
|
327 |
if (is_exiting) { |
|
|
328 |
*retained_globallistmem = NULL; |
329 |
} |
330 |
else if (!is_startup) { |
331 |
*retained_globallistmem = globallistmem; |
332 |
} |
333 |
globallistmem = NULL; |
309 |
globallistmem = NULL; |
334 |
|
|
|
335 |
return APR_SUCCESS; |
310 |
return APR_SUCCESS; |
336 |
} |
311 |
} |
337 |
|
312 |
|
Lines 361-392
static apr_status_t slotmem_doall(ap_slotmem_insta
Link Here
|
361 |
return retval; |
336 |
return retval; |
362 |
} |
337 |
} |
363 |
|
338 |
|
364 |
static int check_slotmem(ap_slotmem_instance_t *mem, apr_size_t size, |
|
|
365 |
apr_size_t item_size, unsigned int item_num) |
366 |
{ |
367 |
sharedslotdesc_t *desc; |
368 |
|
369 |
/* check size */ |
370 |
if (apr_shm_size_get(mem->shm) != size) { |
371 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02599) |
372 |
"existing shared memory for %s could not be used " |
373 |
"(failed size check)", |
374 |
mem->name); |
375 |
return 0; |
376 |
} |
377 |
|
378 |
desc = apr_shm_baseaddr_get(mem->shm); |
379 |
if (desc->size != item_size || desc->num != item_num) { |
380 |
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02600) |
381 |
"existing shared memory for %s could not be used " |
382 |
"(failed contents check)", |
383 |
mem->name); |
384 |
return 0; |
385 |
} |
386 |
|
387 |
return 1; |
388 |
} |
389 |
|
390 |
static apr_status_t slotmem_create(ap_slotmem_instance_t **new, |
339 |
static apr_status_t slotmem_create(ap_slotmem_instance_t **new, |
391 |
const char *name, apr_size_t item_size, |
340 |
const char *name, apr_size_t item_size, |
392 |
unsigned int item_num, |
341 |
unsigned int item_num, |
Lines 405-437
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
405 |
(item_num * sizeof(char)) + basesize; |
354 |
(item_num * sizeof(char)) + basesize; |
406 |
int persist = (type & AP_SLOTMEM_TYPE_PERSIST) != 0; |
355 |
int persist = (type & AP_SLOTMEM_TYPE_PERSIST) != 0; |
407 |
apr_status_t rv; |
356 |
apr_status_t rv; |
408 |
apr_pool_t *p; |
|
|
409 |
|
357 |
|
410 |
*new = NULL; |
358 |
*new = NULL; |
411 |
|
359 |
if (gpool == NULL) { |
|
|
360 |
return APR_ENOSHMAVAIL; |
361 |
} |
412 |
if (slotmem_filenames(pool, name, &fname, persist ? &pname : NULL)) { |
362 |
if (slotmem_filenames(pool, name, &fname, persist ? &pname : NULL)) { |
413 |
/* first try to attach to existing slotmem */ |
363 |
/* first try to attach to existing slotmem */ |
414 |
if (next) { |
364 |
if (next) { |
415 |
ap_slotmem_instance_t *prev = NULL; |
|
|
416 |
for (;;) { |
365 |
for (;;) { |
417 |
if (strcmp(next->name, fname) == 0) { |
366 |
if (strcmp(next->name, fname) == 0) { |
418 |
*new = next; /* either returned here or reused finally */ |
|
|
419 |
if (!check_slotmem(next, size, item_size, item_num)) { |
420 |
apr_shm_destroy(next->shm); |
421 |
next = next->next; |
422 |
if (prev) { |
423 |
prev->next = next; |
424 |
} |
425 |
else { |
426 |
globallistmem = next; |
427 |
} |
428 |
if (next) { |
429 |
continue; |
430 |
} |
431 |
next = prev; |
432 |
break; |
433 |
} |
434 |
/* we already have it */ |
367 |
/* we already have it */ |
|
|
368 |
*new = next; |
435 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02603) |
369 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(02603) |
436 |
"create found %s in global list", fname); |
370 |
"create found %s in global list", fname); |
437 |
return APR_SUCCESS; |
371 |
return APR_SUCCESS; |
Lines 439-445
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
439 |
if (!next->next) { |
373 |
if (!next->next) { |
440 |
break; |
374 |
break; |
441 |
} |
375 |
} |
442 |
prev = next; |
|
|
443 |
next = next->next; |
376 |
next = next->next; |
444 |
} |
377 |
} |
445 |
} |
378 |
} |
Lines 457-467
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
457 |
item_num); |
390 |
item_num); |
458 |
|
391 |
|
459 |
{ |
392 |
{ |
|
|
393 |
/* For MPMs that run pre/post_config() phases in both the parent |
394 |
* and children processes (e.g. winnt), SHMs created by the |
395 |
* parent exist in the children already; attach them. |
396 |
*/ |
460 |
if (fbased) { |
397 |
if (fbased) { |
461 |
/* For MPMs (e.g. winnt) that run pre/post_config() phases in |
|
|
462 |
* both the parent and children processes, SHMs created by the |
463 |
* parent exist in the children already; only attach them. |
464 |
*/ |
465 |
if (is_child_process()) { |
398 |
if (is_child_process()) { |
466 |
rv = apr_shm_attach(&shm, fname, gpool); |
399 |
rv = apr_shm_attach(&shm, fname, gpool); |
467 |
} |
400 |
} |
Lines 471-477
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
471 |
} |
404 |
} |
472 |
} |
405 |
} |
473 |
else { |
406 |
else { |
474 |
rv = apr_shm_create(&shm, size, NULL, pool); |
407 |
rv = apr_shm_create(&shm, size, NULL, gpool); |
475 |
} |
408 |
} |
476 |
ap_log_error(APLOG_MARK, rv == APR_SUCCESS ? APLOG_DEBUG : APLOG_ERR, |
409 |
ap_log_error(APLOG_MARK, rv == APR_SUCCESS ? APLOG_DEBUG : APLOG_ERR, |
477 |
rv, ap_server_conf, APLOGNO(02611) |
410 |
rv, ap_server_conf, APLOGNO(02611) |
Lines 501-507
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
501 |
} |
434 |
} |
502 |
else { |
435 |
else { |
503 |
/* just in case, re-zero */ |
436 |
/* just in case, re-zero */ |
504 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, |
437 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, |
505 |
APLOGNO(02554) "could not restore %s", fname); |
438 |
APLOGNO(02554) "could not restore %s", fname); |
506 |
memset((char *)desc + AP_SLOTMEM_OFFSET, 0, |
439 |
memset((char *)desc + AP_SLOTMEM_OFFSET, 0, |
507 |
size - AP_SLOTMEM_OFFSET); |
440 |
size - AP_SLOTMEM_OFFSET); |
Lines 509-525
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
509 |
} |
442 |
} |
510 |
} |
443 |
} |
511 |
|
444 |
|
512 |
p = fbased ? gpool : pool; |
|
|
513 |
ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
445 |
ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
514 |
|
446 |
|
515 |
/* For the chained slotmem stuff (*new may be reused from above) */ |
447 |
/* For the chained slotmem stuff */ |
516 |
res = *new; |
448 |
res = apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t)); |
517 |
if (res == NULL) { |
449 |
res->name = apr_pstrdup(gpool, fname); |
518 |
res = apr_pcalloc(p, sizeof(ap_slotmem_instance_t)); |
450 |
res->pname = apr_pstrdup(gpool, pname); |
519 |
res->name = apr_pstrdup(p, fname); |
|
|
520 |
res->pname = apr_pstrdup(p, pname); |
521 |
*new = res; |
522 |
} |
523 |
res->fbased = fbased; |
451 |
res->fbased = fbased; |
524 |
res->shm = shm; |
452 |
res->shm = shm; |
525 |
res->persist = (void *)ptr; |
453 |
res->persist = (void *)ptr; |
Lines 530-536
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
530 |
} |
458 |
} |
531 |
res->base = (void *)ptr; |
459 |
res->base = (void *)ptr; |
532 |
res->desc = desc; |
460 |
res->desc = desc; |
533 |
res->pool = pool; |
461 |
res->gpool = gpool; |
534 |
res->next = NULL; |
462 |
res->next = NULL; |
535 |
res->inuse = ptr + basesize; |
463 |
res->inuse = ptr + basesize; |
536 |
if (fbased) { |
464 |
if (fbased) { |
Lines 542-547
static apr_status_t slotmem_create(ap_slotmem_inst
Link Here
|
542 |
} |
470 |
} |
543 |
} |
471 |
} |
544 |
|
472 |
|
|
|
473 |
*new = res; |
545 |
return APR_SUCCESS; |
474 |
return APR_SUCCESS; |
546 |
} |
475 |
} |
547 |
|
476 |
|
Lines 549-555
static apr_status_t slotmem_attach(ap_slotmem_inst
Link Here
|
549 |
const char *name, apr_size_t *item_size, |
478 |
const char *name, apr_size_t *item_size, |
550 |
unsigned int *item_num, apr_pool_t *pool) |
479 |
unsigned int *item_num, apr_pool_t *pool) |
551 |
{ |
480 |
{ |
552 |
/* void *slotmem = NULL; */ |
|
|
553 |
char *ptr; |
481 |
char *ptr; |
554 |
ap_slotmem_instance_t *res; |
482 |
ap_slotmem_instance_t *res; |
555 |
ap_slotmem_instance_t *next = globallistmem; |
483 |
ap_slotmem_instance_t *next = globallistmem; |
Lines 558-563
static apr_status_t slotmem_attach(ap_slotmem_inst
Link Here
|
558 |
apr_shm_t *shm; |
486 |
apr_shm_t *shm; |
559 |
apr_status_t rv; |
487 |
apr_status_t rv; |
560 |
|
488 |
|
|
|
489 |
if (gpool == NULL) { |
490 |
return APR_ENOSHMAVAIL; |
491 |
} |
561 |
if (!slotmem_filenames(pool, name, &fname, NULL)) { |
492 |
if (!slotmem_filenames(pool, name, &fname, NULL)) { |
562 |
return APR_ENOSHMAVAIL; |
493 |
return APR_ENOSHMAVAIL; |
563 |
} |
494 |
} |
Lines 587-593
static apr_status_t slotmem_attach(ap_slotmem_inst
Link Here
|
587 |
} |
518 |
} |
588 |
|
519 |
|
589 |
/* next try to attach to existing shared memory */ |
520 |
/* next try to attach to existing shared memory */ |
590 |
rv = apr_shm_attach(&shm, fname, pool); |
521 |
rv = apr_shm_attach(&shm, fname, gpool); |
591 |
if (rv != APR_SUCCESS) { |
522 |
if (rv != APR_SUCCESS) { |
592 |
return rv; |
523 |
return rv; |
593 |
} |
524 |
} |
Lines 597-604
static apr_status_t slotmem_attach(ap_slotmem_inst
Link Here
|
597 |
ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
528 |
ptr = (char *)desc + AP_SLOTMEM_OFFSET; |
598 |
|
529 |
|
599 |
/* For the chained slotmem stuff */ |
530 |
/* For the chained slotmem stuff */ |
600 |
res = apr_pcalloc(pool, sizeof(ap_slotmem_instance_t)); |
531 |
res = apr_pcalloc(gpool, sizeof(ap_slotmem_instance_t)); |
601 |
res->name = apr_pstrdup(pool, fname); |
532 |
res->name = apr_pstrdup(gpool, fname); |
602 |
res->fbased = 1; |
533 |
res->fbased = 1; |
603 |
res->shm = shm; |
534 |
res->shm = shm; |
604 |
res->persist = (void *)ptr; |
535 |
res->persist = (void *)ptr; |
Lines 606-612
static apr_status_t slotmem_attach(ap_slotmem_inst
Link Here
|
606 |
ptr += AP_UNSIGNEDINT_OFFSET; |
537 |
ptr += AP_UNSIGNEDINT_OFFSET; |
607 |
res->base = (void *)ptr; |
538 |
res->base = (void *)ptr; |
608 |
res->desc = desc; |
539 |
res->desc = desc; |
609 |
res->pool = pool; |
540 |
res->gpool = gpool; |
610 |
res->inuse = ptr + (desc->size * desc->num); |
541 |
res->inuse = ptr + (desc->size * desc->num); |
611 |
res->next = NULL; |
542 |
res->next = NULL; |
612 |
|
543 |
|
Lines 821-863
static const ap_slotmem_provider_t *slotmem_shm_ge
Link Here
|
821 |
return (&storage); |
752 |
return (&storage); |
822 |
} |
753 |
} |
823 |
|
754 |
|
824 |
/* Initialize or reuse the retained slotmems list, and register the |
755 |
/* |
825 |
* cleanup to make sure the persisted SHMs are stored and the retained |
756 |
* Make sure the shared memory is cleaned |
826 |
* data are up to date on next restart/stop. |
|
|
827 |
*/ |
757 |
*/ |
828 |
static int pre_config(apr_pool_t *pconf, apr_pool_t *plog, |
758 |
static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, |
829 |
apr_pool_t *ptemp) |
759 |
server_rec *s) |
830 |
{ |
760 |
{ |
831 |
void *is_startup = NULL; |
761 |
apr_pool_cleanup_register(p, NULL, cleanup_slotmem, apr_pool_cleanup_null); |
832 |
const char *retained_key = "mod_slotmem_shm"; |
762 |
return OK; |
|
|
763 |
} |
833 |
|
764 |
|
834 |
retained_globallistmem = ap_retained_data_get(retained_key); |
765 |
static int pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) |
835 |
if (!retained_globallistmem) { |
766 |
{ |
836 |
retained_globallistmem = |
767 |
gpool = p; |
837 |
ap_retained_data_create(retained_key, |
768 |
globallistmem = NULL; |
838 |
sizeof *retained_globallistmem); |
|
|
839 |
} |
840 |
globallistmem = *retained_globallistmem; |
841 |
|
842 |
/* For the first (dry-)loading or children in MPMs which (re-)run |
843 |
* pre_config we don't need to retain slotmems, so use pconf and its |
844 |
* normal cleanups. Otherwise we use ap_pglobal to match the lifetime |
845 |
* of retained data and register our own cleanup to update them. |
846 |
*/ |
847 |
if (is_child_process()) { |
848 |
gpool = pconf; |
849 |
} |
850 |
else if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) { |
851 |
gpool = ap_pglobal; |
852 |
} |
853 |
else { |
854 |
is_startup = (void *)1; |
855 |
gpool = pconf; |
856 |
} |
857 |
|
858 |
apr_pool_cleanup_register(pconf, is_startup, cleanup_slotmem, |
859 |
apr_pool_cleanup_null); |
860 |
|
861 |
return OK; |
769 |
return OK; |
862 |
} |
770 |
} |
863 |
|
771 |
|
Lines 866-871
static void ap_slotmem_shm_register_hook(apr_pool_
Link Here
|
866 |
const ap_slotmem_provider_t *storage = slotmem_shm_getstorage(); |
774 |
const ap_slotmem_provider_t *storage = slotmem_shm_getstorage(); |
867 |
ap_register_provider(p, AP_SLOTMEM_PROVIDER_GROUP, "shm", |
775 |
ap_register_provider(p, AP_SLOTMEM_PROVIDER_GROUP, "shm", |
868 |
AP_SLOTMEM_PROVIDER_VERSION, storage); |
776 |
AP_SLOTMEM_PROVIDER_VERSION, storage); |
|
|
777 |
ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_LAST); |
869 |
ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE); |
778 |
ap_hook_pre_config(pre_config, NULL, NULL, APR_HOOK_MIDDLE); |
870 |
} |
779 |
} |
871 |
|
780 |
|