You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2004/06/17 16:13:58 UTC

cvs commit: apr/test testpools.c

jorton      2004/06/17 07:13:58

  Modified:    memory/unix apr_pools.c
               test     testpools.c
  Log:
  Reuse cleanup structures to prevent memory consumption from repeated
  register/kill of a cleanup against a single pool:
  
  * memory/unix/apr_pools.c (struct apr_pool_t): Add freelist for
  cleanup structures.
  (apr_pool_cleanup_kill): Move used cleanup structures onto the
  freelist.
  (apr_pool_cleanup_register): Reuse cleanup structure if available.
  (apr_pool_clear, pool_clear_debug, apr_pool_create): Clear the freelist.
  
  * test/testpools.c (checker_cleanup, success_cleanup, test_cleanups):
  Add tests for cleanups.
  
  PR: 23567 (the easy half)
  
  Revision  Changes    Path
  1.206     +14 -1     apr/memory/unix/apr_pools.c
  
  Index: apr_pools.c
  ===================================================================
  RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
  retrieving revision 1.205
  retrieving revision 1.206
  diff -d -w -u -r1.205 -r1.206
  --- apr_pools.c	13 Feb 2004 09:38:32 -0000	1.205
  +++ apr_pools.c	17 Jun 2004 14:13:58 -0000	1.206
  @@ -435,6 +435,7 @@
       apr_pool_t           *sibling;
       apr_pool_t          **ref;
       cleanup_t            *cleanups;
  +    cleanup_t            *free_cleanups;
       apr_allocator_t      *allocator;
       struct process_chain *subprocesses;
       apr_abortfunc_t       abort_fn;
  @@ -674,6 +675,7 @@
       /* Run cleanups */
       run_cleanups(&pool->cleanups);
       pool->cleanups = NULL;
  +    pool->free_cleanups = NULL;
   
       /* Free subprocesses */
       free_proc_chain(pool->subprocesses);
  @@ -801,6 +803,7 @@
       pool->abort_fn = abort_fn;
       pool->child = NULL;
       pool->cleanups = NULL;
  +    pool->free_cleanups = NULL;
       pool->subprocesses = NULL;
       pool->user_data = NULL;
       pool->tag = NULL;
  @@ -1340,6 +1343,7 @@
   
       /* Run cleanups */
       run_cleanups(&pool->cleanups);
  +    pool->free_cleanups = NULL;
       pool->cleanups = NULL;
   
       /* If new child pools showed up, this is a reason to raise a flag */
  @@ -1886,7 +1890,13 @@
   #endif /* APR_POOL_DEBUG */
   
       if (p != NULL) {
  -        c = (cleanup_t *)apr_palloc(p, sizeof(cleanup_t));
  +        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;
  @@ -1912,6 +1922,9 @@
       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;
           }
   
  
  
  
  1.13      +48 -0     apr/test/testpools.c
  
  Index: testpools.c
  ===================================================================
  RCS file: /home/cvs/apr/test/testpools.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -d -w -u -r1.12 -r1.13
  --- testpools.c	14 May 2004 14:43:22 -0000	1.12
  +++ testpools.c	17 Jun 2004 14:13:58 -0000	1.13
  @@ -91,6 +91,53 @@
       ABTS_INT_EQUAL(tc, 0, apr_pool_is_ancestor(pchild, pmain));
   }
   
  +static apr_status_t success_cleanup(void *data)
  +{
  +    return APR_SUCCESS;
  +}
  +
  +static char *checker_data = "Hello, world.";
  +
  +static apr_status_t checker_cleanup(void *data)
  +{
  +    return data == checker_data ? APR_SUCCESS : APR_EGENERAL;
  +}
  +
  +static void test_cleanups(abts_case *tc, void *data)
  +{
  +    apr_status_t rv;
  +    int n;
  +
  +    /* do this several times to test the cleanup freelist handling. */
  +    for (n = 0; n < 5; n++) {
  +        apr_pool_cleanup_register(pchild, NULL, success_cleanup,
  +                                  success_cleanup);
  +        apr_pool_cleanup_register(pchild, checker_data, checker_cleanup,
  +                                  success_cleanup);
  +        apr_pool_cleanup_register(pchild, NULL, checker_cleanup, 
  +                                  success_cleanup);
  +
  +        rv = apr_pool_cleanup_run(p, NULL, success_cleanup);
  +        ABTS_ASSERT(tc, "nullop cleanup run OK", rv == APR_SUCCESS);
  +        rv = apr_pool_cleanup_run(p, checker_data, checker_cleanup);
  +        ABTS_ASSERT(tc, "cleanup passed correct data", rv == APR_SUCCESS);
  +        rv = apr_pool_cleanup_run(p, NULL, checker_cleanup);
  +        ABTS_ASSERT(tc, "cleanup passed correct data", rv == APR_EGENERAL);
  +
  +        if (n == 2) {
  +            /* clear the pool to check that works */
  +            apr_pool_clear(pchild);
  +        }
  +
  +        if (n % 2 == 0) {
  +            /* throw another random cleanup into the mix */
  +            apr_pool_cleanup_register(pchild, NULL,
  +                                      apr_pool_cleanup_null,
  +                                      apr_pool_cleanup_null);
  +        }
  +    }
  +}
  +
   abts_suite *testpool(abts_suite *suite)
   {
       suite = ADD_SUITE(suite)
  @@ -101,6 +148,7 @@
       abts_run_test(suite, test_notancestor, NULL);
       abts_run_test(suite, alloc_bytes, NULL);
       abts_run_test(suite, calloc_bytes, NULL);
  +    abts_run_test(suite, test_cleanups, NULL);
   
       return suite;
   }