2010-09-02 21 views
1

Mon application est construite avec apache et fonctionne sur Windows. Je crée un fil à l'aide du CreateThread(), puis pour chaque thread exécutant le ci-dessous:apr_pool_destroy() de thread Apache est-il sûr?

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

Le ap_destroy_sub_request appelle à son tour la fonction apr_pool_destroy().

La mémoire allouée par ap_run_sub_req() pour pool et ap_destroy_sub_req() libère la mémoire allouée.

Si la fonction apr_pool_destroy() est appelée dans un thread, la mémoire allouée n'est pas libérée, ce qui entraîne une perte de mémoire pour l'application. Je n'ai trouvé dans aucune documentation d'apache la mention de apr_pool_destroy() étant des fonctions non-thread-safe.

Comment ce problème peut-il être résolu? Comment puis-je libérer le pool alloué dans les threads?
Merci

Répondre

1

Voici le code source pour 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); 
    } 
} 

Des regards de celui-ci, il est thread-safe, mais je ne suis pas un expert en C. Vous devriez probablement poster sur the APR mailing list.