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;
}