📄 apr_pools.c
字号:
{ void *pool = (void *)mem; if (apr_pool_walk_tree(global_pool, pool_find, &pool)) return pool; return NULL;}static int pool_num_bytes(apr_pool_t *pool, void *data){ apr_size_t *psize = (apr_size_t *)data; debug_node_t *node; apr_uint32_t index; node = pool->nodes; while (node) { for (index = 0; index < node->index; index++) { *psize += (char *)node->endp[index] - (char *)node->beginp[index]; } node = node->next; } return 0;}APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *pool, int recurse){ apr_size_t size = 0; if (!recurse) { pool_num_bytes(pool, &size); return size; } apr_pool_walk_tree(pool, pool_num_bytes, &size); return size;}APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool, int flag){}#endif /* !APR_POOL_DEBUG */#ifdef NETWAREvoid netware_pool_proc_cleanup (){ apr_pool_t *pool = global_pool->child; apr_os_proc_t owner_proc = (apr_os_proc_t)getnlmhandle(); while (pool) { if (pool->owner_proc == owner_proc) { apr_pool_destroy (pool); pool = global_pool->child; } else { pool = pool->sibling; } } return;}#endif /* defined(NETWARE) *//* * "Print" functions (common) */APR_DECLARE_NONSTD(char *) apr_psprintf(apr_pool_t *p, const char *fmt, ...){ va_list ap; char *res; va_start(ap, fmt); res = apr_pvsprintf(p, fmt, ap); va_end(ap); return res;}/* * Pool Properties */APR_DECLARE(void) apr_pool_abort_set(apr_abortfunc_t abort_fn, apr_pool_t *pool){ pool->abort_fn = abort_fn;}APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool){ return pool->abort_fn;}APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool){#ifdef NETWARE /* On NetWare, don't return the global_pool, return the application pool as the top most pool */ if (pool->parent == global_pool) return NULL; else#endif return pool->parent;}APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool){ return pool->allocator;}/* return TRUE if a is an ancestor of b * NULL is considered an ancestor of all pools */APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b){ if (a == NULL) return 1;#if APR_POOL_DEBUG /* Find the pool with the longest lifetime guaranteed by the * caller: */ while (a->joined) { a = a->joined; }#endif while (b) { if (a == b) return 1; b = b->parent; } return 0;}APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag){ pool->tag = tag;}/* * User data management */APR_DECLARE(apr_status_t) apr_pool_userdata_set(const void *data, const char *key, apr_status_t (*cleanup) (void *), apr_pool_t *pool){#if APR_POOL_DEBUG apr_pool_check_integrity(pool);#endif /* APR_POOL_DEBUG */ if (pool->user_data == NULL) pool->user_data = apr_hash_make(pool); if (apr_hash_get(pool->user_data, key, APR_HASH_KEY_STRING) == NULL) { char *new_key = apr_pstrdup(pool, key); apr_hash_set(pool->user_data, new_key, APR_HASH_KEY_STRING, data); } else { apr_hash_set(pool->user_data, key, APR_HASH_KEY_STRING, data); } if (cleanup) apr_pool_cleanup_register(pool, data, cleanup, cleanup); return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_pool_userdata_setn(const void *data, const char *key, apr_status_t (*cleanup)(void *), apr_pool_t *pool){#if APR_POOL_DEBUG apr_pool_check_integrity(pool);#endif /* APR_POOL_DEBUG */ if (pool->user_data == NULL) pool->user_data = apr_hash_make(pool); apr_hash_set(pool->user_data, key, APR_HASH_KEY_STRING, data); if (cleanup) apr_pool_cleanup_register(pool, data, cleanup, cleanup); return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key, apr_pool_t *pool){#if APR_POOL_DEBUG apr_pool_check_integrity(pool);#endif /* APR_POOL_DEBUG */ if (pool->user_data == NULL) { *data = NULL; } else { *data = apr_hash_get(pool->user_data, key, APR_HASH_KEY_STRING); } return APR_SUCCESS;}/* * Cleanup */struct cleanup_t { struct cleanup_t *next; const void *data; apr_status_t (*plain_cleanup_fn)(void *data); apr_status_t (*child_cleanup_fn)(void *data);};APR_DECLARE(void) apr_pool_cleanup_register(apr_pool_t *p, const void *data, apr_status_t (*plain_cleanup_fn)(void *data), apr_status_t (*child_cleanup_fn)(void *data)){ cleanup_t *c;#if APR_POOL_DEBUG apr_pool_check_integrity(p);#endif /* APR_POOL_DEBUG */ if (p != NULL) { if (p->free_cleanups) { /* reuse a cleanup structure */ c = p->free_cleanups; p->free_cleanups = c->next; } else { c = apr_palloc(p, sizeof(cleanup_t)); } c->data = data; c->plain_cleanup_fn = plain_cleanup_fn; c->child_cleanup_fn = child_cleanup_fn; c->next = p->cleanups; p->cleanups = c; }}APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data, apr_status_t (*cleanup_fn)(void *)){ cleanup_t *c, **lastp;#if APR_POOL_DEBUG apr_pool_check_integrity(p);#endif /* APR_POOL_DEBUG */ if (p == NULL) return; c = p->cleanups; lastp = &p->cleanups; while (c) { if (c->data == data && c->plain_cleanup_fn == cleanup_fn) { *lastp = c->next; /* move to freelist */ c->next = p->free_cleanups; p->free_cleanups = c; break; } lastp = &c->next; c = c->next; }}APR_DECLARE(void) apr_pool_child_cleanup_set(apr_pool_t *p, const void *data, apr_status_t (*plain_cleanup_fn)(void *), apr_status_t (*child_cleanup_fn)(void *)){ cleanup_t *c;#if APR_POOL_DEBUG apr_pool_check_integrity(p);#endif /* APR_POOL_DEBUG */ if (p == NULL) return; c = p->cleanups; while (c) { if (c->data == data && c->plain_cleanup_fn == plain_cleanup_fn) { c->child_cleanup_fn = child_cleanup_fn; break; } c = c->next; }}APR_DECLARE(apr_status_t) apr_pool_cleanup_run(apr_pool_t *p, void *data, apr_status_t (*cleanup_fn)(void *)){ apr_pool_cleanup_kill(p, data, cleanup_fn); return (*cleanup_fn)(data);}static void run_cleanups(cleanup_t **cref){ cleanup_t *c = *cref; while (c) { *cref = c->next; (*c->plain_cleanup_fn)((void *)c->data); c = *cref; }}static void run_child_cleanups(cleanup_t **cref){ cleanup_t *c = *cref; while (c) { *cref = c->next; (*c->child_cleanup_fn)((void *)c->data); c = *cref; }}static void cleanup_pool_for_exec(apr_pool_t *p){ run_child_cleanups(&p->cleanups); for (p = p->child; p; p = p->sibling) cleanup_pool_for_exec(p);}APR_DECLARE(void) apr_pool_cleanup_for_exec(void){#if !defined(WIN32) && !defined(OS2) /* * Don't need to do anything on NT or OS/2, because I * am actually going to spawn the new process - not * exec it. All handles that are not inheritable, will * be automajically closed. The only problem is with * file handles that are open, but there isn't much * I can do about that (except if the child decides * to go out and close them */ cleanup_pool_for_exec(global_pool);#endif /* !defined(WIN32) && !defined(OS2) */}APR_DECLARE_NONSTD(apr_status_t) apr_pool_cleanup_null(void *data){ /* do nothing cleanup routine */ return APR_SUCCESS;}/* Subprocesses don't use the generic cleanup interface because * we don't want multiple subprocesses to result in multiple * three-second pauses; the subprocesses have to be "freed" all * at once. If other resources are introduced with the same property, * we might want to fold support for that into the generic interface. * For now, it's a special case. */APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *pool, apr_proc_t *proc, apr_kill_conditions_e how){ struct process_chain *pc = apr_palloc(pool, sizeof(struct process_chain)); pc->proc = proc; pc->kill_how = how; pc->next = pool->subprocesses; pool->subprocesses = pc;}static void free_proc_chain(struct process_chain *procs){ /* Dispose of the subprocesses we've spawned off in the course of * whatever it was we're cleaning up now. This may involve killing * some of them off... */ struct process_chain *pc; int need_timeout = 0; apr_time_t timeout_interval; if (!procs) return; /* No work. Whew! */ /* First, check to see if we need to do the SIGTERM, sleep, SIGKILL * dance with any of the processes we're cleaning up. If we've got * any kill-on-sight subprocesses, ditch them now as well, so they * don't waste any more cycles doing whatever it is that they shouldn't * be doing anymore. */#ifndef NEED_WAITPID /* Pick up all defunct processes */ for (pc = procs; pc; pc = pc->next) { if (apr_proc_wait(pc->proc, NULL, NULL, APR_NOWAIT) != APR_CHILD_NOTDONE) pc->kill_how = APR_KILL_NEVER; }#endif /* !defined(NEED_WAITPID) */ for (pc = procs; pc; pc = pc->next) {#ifndef WIN32 if ((pc->kill_how == APR_KILL_AFTER_TIMEOUT) || (pc->kill_how == APR_KILL_ONLY_ONCE)) { /* * Subprocess may be dead already. Only need the timeout if not. * Note: apr_proc_kill on Windows is TerminateProcess(), which is * similar to a SIGKILL, so always give the process a timeout * under Windows before killing it. */ if (apr_proc_kill(pc->proc, SIGTERM) == APR_SUCCESS) need_timeout = 1; } else if (pc->kill_how == APR_KILL_ALWAYS) {#else /* WIN32 knows only one fast, clean method of killing processes today */ if (pc->kill_how != APR_KILL_NEVER) { need_timeout = 1; pc->kill_how = APR_KILL_ALWAYS;#endif apr_proc_kill(pc->proc, SIGKILL); } } /* Sleep only if we have to. The sleep algorithm grows * by a factor of two on each iteration. TIMEOUT_INTERVAL * is equal to TIMEOUT_USECS / 64. */ if (need_timeout) { timeout_interval = TIMEOUT_INTERVAL; apr_sleep(timeout_interval); do { /* check the status of the subprocesses */ need_timeout = 0; for (pc = procs; pc; pc = pc->next) { if (pc->kill_how == APR_KILL_AFTER_TIMEOUT) { if (apr_proc_wait(pc->proc, NULL, NULL, APR_NOWAIT) == APR_CHILD_NOTDONE) need_timeout = 1; /* subprocess is still active */ else pc->kill_how = APR_KILL_NEVER; /* subprocess has exited */ } } if (need_timeout) { if (timeout_interval >= TIMEOUT_USECS) { break; } apr_sleep(timeout_interval); timeout_interval *= 2; } } while (need_timeout); } /* OK, the scripts we just timed out for have had a chance to clean up * --- now, just get rid of them, and also clean up the system accounting * goop... */ for (pc = procs; pc; pc = pc->next) { if (pc->kill_how == APR_KILL_AFTER_TIMEOUT) apr_proc_kill(pc->proc, SIGKILL); } /* Now wait for all the signaled processes to die */ for (pc = procs; pc; pc = pc->next) { if (pc->kill_how != APR_KILL_NEVER) (void)apr_proc_wait(pc->proc, NULL, NULL, APR_WAIT); }}/* * Pool creation/destruction stubs, for people who are running * mixed release/debug enviroments. */#if !APR_POOL_DEBUGAPR_DECLARE(void *) apr_palloc_debug(apr_pool_t *pool, apr_size_t size, const char *file_line){ return apr_palloc(pool, size);}APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *pool, apr_size_t size, const char *file_line){ return apr_pcalloc(pool, size);}APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, const char *file_line){ apr_pool_clear(pool);}APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *pool, const char *file_line){ apr_pool_destroy(pool);}APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, const char *file_line){ return apr_pool_create_ex(newpool, parent, abort_fn, allocator);}#else /* APR_POOL_DEBUG */#undef apr_pallocAPR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size);APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size){ return apr_palloc_debug(pool, size, "undefined");}#undef apr_pcallocAPR_DECLARE(void *) apr_pcalloc(apr_pool_t *pool, apr_size_t size);APR_DECLARE(void *) apr_pcalloc(apr_pool_t *pool, apr_size_t size){ return apr_pcalloc_debug(pool, size, "undefined");}#undef apr_pool_clearAPR_DECLARE(void) apr_pool_clear(apr_pool_t *pool);APR_DECLARE(void) apr_pool_clear(apr_pool_t *pool){ apr_pool_clear_debug(pool, "undefined");}#undef apr_pool_destroyAPR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool);APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool){ apr_pool_destroy_debug(pool, "undefined");}#undef apr_pool_create_exAPR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator);APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator){ return apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, "undefined");}#endif /* APR_POOL_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -