dev  

Re: svn commit: r677505 - /apr/apr-util/trunk/misc/apr_reslist.c

Bojan Smojver
Thu, 17 Jul 2008 21:52:30 -0700

On Fri, 2008-07-18 at 06:25 +0200, Mladen Turk wrote:

> With regular cleanup this should core.

It doesn't here, not even when I do millions loops (i.e. with your k
index and explicit apr_pool_destroy(pool));

> Try to random acquire/release resources and do few loops.

What do you mean by random? All resources must be released back to the
list before destroying the list.

The attached prints "data" 5.5 million times and doesn't segfault. This
is APU with regular cleanup on reslist.

My understanding is that your patch affects creation of sub-pools only
in the destructor. No?

-- 
Bojan
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <apr.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_reslist.h>

struct res{
  apr_pool_t *p;
  char *r;
};

struct sub{
  struct res *r; /* parent resource */
  char *s;
};

static apr_status_t res_clean(void *data){
  struct res *r=data;

  free(r->r);
  r->r=NULL;

  return APR_SUCCESS;
}

static apr_status_t sub_clean(void *data){
  struct sub *s=data;

  /* use parent resource a bit */
  printf("%s\n",s->r->r);

  free(s->s);
  s->s=NULL;

  return APR_SUCCESS;
}

static apr_status_t con(void **res,void *parm,apr_pool_t *pool){
  apr_pool_t *rpool,*spool;
  struct res **r=(struct res **)res;
  struct sub *s;

  apr_pool_create(&rpool,pool);
  *r=apr_pcalloc(rpool,sizeof(**r));
  (*r)->p=rpool;
  (*r)->r=malloc(5);
  memcpy((*r)->r,"data",5);
  apr_pool_cleanup_register(rpool,*r,res_clean,apr_pool_cleanup_null);

  apr_pool_create(&spool,rpool);
  s=apr_pcalloc(spool,sizeof(*s));
  s->r=*r;
  s->s=malloc(5);
  memcpy(s->s,"data",5);
  apr_pool_cleanup_register(spool,s,sub_clean,apr_pool_cleanup_null);

  return APR_SUCCESS;
}

static apr_status_t de(void *res,void *parm,apr_pool_t *pool){
  struct res *r=res;

  apr_pool_destroy(r->p);

  return APR_SUCCESS;
}

int main(int argc,char **argv){
  int i,j,k;
  struct res *r[10];
  apr_pool_t *pool;
  apr_reslist_t *list;

  apr_initialize();

  for(k=0;k<100000;k++){
    apr_pool_create(&pool,NULL);

    apr_reslist_create(&list,0,0,10,0,con,de,NULL,pool);

    for(j=1;j<=10;j++){
      for(i=0;i<j;i++)
        apr_reslist_acquire(list,(void **)&r[i]);

      for(i=0;i<j;i++)
        apr_reslist_release(list,r[i]);
    }

    apr_pool_destroy(pool);
  }

  apr_terminate();
  return 0;
}