apache线程的apr_pool_destroy()安全吗?

发布于 2024-09-17 07:50:05 字数 484 浏览 22 评论 0原文

我的应用程序是用 apache 构建的并在 Windows 上运行。我使用 createThread() 创建一个线程,然后为每个线程执行以下操作:

ap_run_sub_req( subrequest );   
ap_rflush( subrequest );  
ap_destroy_sub_req( subrequest );  

ap_destroy_sub_request 依次调用 apr_pool_destroy() 函数。

ap_run_sub_req() 为池分配内存, ap_destroy_sub_req() 释放分配的内存。

如果 apr_pool_destroy() 在线程内调用,则分配的内存不会被释放,导致我的应用程序出现内存泄漏。我在任何 apache 文档中都找不到任何提及 apr_pool_destroy() 是非线程安全函数的内容。

这个问题如何解决?如何释放线程内分配的池?
谢谢

My application is built with apache and runs on windows. I am creating a Thread using the createThread() and then for each thread executing the below :

ap_run_sub_req( subrequest );   
ap_rflush( subrequest );  
ap_destroy_sub_req( subrequest );  

The ap_destroy_sub_request in turn calls apr_pool_destroy() function.

The ap_run_sub_req() allocated memory for pool and ap_destroy_sub_req() frees the allocated memory.

If the apr_pool_destroy() is called inside a thread then the allocated memory is not freed as a result my application is having memory leak. I couldn't find in any apache documentation any mention of apr_pool_destroy() being non-thread safe functions.

How can this problem be resolved ?? How can I free the allocated pool inside the threads?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌路黄昏 2024-09-24 07:50:43

这是apr_pool_destroy()的源代码:

APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool)
{
    apr_memnode_t *active;
    apr_allocator_t *allocator;

    /* Run pre destroy cleanups */
    run_cleanups(&pool->pre_cleanups);
    pool->pre_cleanups = NULL;

    /* Destroy the subpools.  The subpools will detach themselve from
     * this pool thus this loop is safe and easy.
     */
    while (pool->child)
        apr_pool_destroy(pool->child);

    /* Run cleanups */
    run_cleanups(&pool->cleanups);

    /* Free subprocesses */
    free_proc_chain(pool->subprocesses);

    /* Remove the pool from the parents child list */
    if (pool->parent) {
#if APR_HAS_THREADS
        apr_thread_mutex_t *mutex;

        if ((mutex = apr_allocator_mutex_get(pool->parent->allocator)) != NULL)
            apr_thread_mutex_lock(mutex);
#endif /* APR_HAS_THREADS */

        if ((*pool->ref = pool->sibling) != NULL)
            pool->sibling->ref = pool->ref;

#if APR_HAS_THREADS
        if (mutex)
            apr_thread_mutex_unlock(mutex);
#endif /* APR_HAS_THREADS */
    }

    /* Find the block attached to the pool structure.  Save a copy of the
     * allocator pointer, because the pool struct soon will be no more.
     */
    allocator = pool->allocator;
    active = pool->self;
    *active->ref = NULL;

#if APR_HAS_THREADS
    if (apr_allocator_owner_get(allocator) == pool) {
        /* Make sure to remove the lock, since it is highly likely to
         * be invalid now.
         */
        apr_allocator_mutex_set(allocator, NULL);
    }
#endif /* APR_HAS_THREADS */

    /* Free all the nodes in the pool (including the node holding the
     * pool struct), by giving them back to the allocator.
     */
    allocator_free(allocator, active);

    /* If this pool happens to be the owner of the allocator, free
     * everything in the allocator (that includes the pool struct
     * and the allocator).  Don't worry about destroying the optional mutex
     * in the allocator, it will have been destroyed by the cleanup function.
     */
    if (apr_allocator_owner_get(allocator) == pool) {
        apr_allocator_destroy(allocator);
    }
}

从它的外观来看,它不是线程安全的,但我不是C专家。您可能应该在APR 邮件列表上发帖。

Here's the source code for apr_pool_destroy():

APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool)
{
    apr_memnode_t *active;
    apr_allocator_t *allocator;

    /* Run pre destroy cleanups */
    run_cleanups(&pool->pre_cleanups);
    pool->pre_cleanups = NULL;

    /* Destroy the subpools.  The subpools will detach themselve from
     * this pool thus this loop is safe and easy.
     */
    while (pool->child)
        apr_pool_destroy(pool->child);

    /* Run cleanups */
    run_cleanups(&pool->cleanups);

    /* Free subprocesses */
    free_proc_chain(pool->subprocesses);

    /* Remove the pool from the parents child list */
    if (pool->parent) {
#if APR_HAS_THREADS
        apr_thread_mutex_t *mutex;

        if ((mutex = apr_allocator_mutex_get(pool->parent->allocator)) != NULL)
            apr_thread_mutex_lock(mutex);
#endif /* APR_HAS_THREADS */

        if ((*pool->ref = pool->sibling) != NULL)
            pool->sibling->ref = pool->ref;

#if APR_HAS_THREADS
        if (mutex)
            apr_thread_mutex_unlock(mutex);
#endif /* APR_HAS_THREADS */
    }

    /* Find the block attached to the pool structure.  Save a copy of the
     * allocator pointer, because the pool struct soon will be no more.
     */
    allocator = pool->allocator;
    active = pool->self;
    *active->ref = NULL;

#if APR_HAS_THREADS
    if (apr_allocator_owner_get(allocator) == pool) {
        /* Make sure to remove the lock, since it is highly likely to
         * be invalid now.
         */
        apr_allocator_mutex_set(allocator, NULL);
    }
#endif /* APR_HAS_THREADS */

    /* Free all the nodes in the pool (including the node holding the
     * pool struct), by giving them back to the allocator.
     */
    allocator_free(allocator, active);

    /* If this pool happens to be the owner of the allocator, free
     * everything in the allocator (that includes the pool struct
     * and the allocator).  Don't worry about destroying the optional mutex
     * in the allocator, it will have been destroyed by the cleanup function.
     */
    if (apr_allocator_owner_get(allocator) == pool) {
        apr_allocator_destroy(allocator);
    }
}

From the looks of it, it's not thread-safe, but I'm not a C expert. You should probably post on the APR mailing list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文