On Sun, 14 Mar 2004, Jeff Trawick wrote: > see comments in PR 26050 about discrepancy in prototypes that seems to show an > underlying issue; apps don't see apr_res_t, so some rework and testing is > needed
It's a fair cop guv. The resource is detached when it's issued, so invalidate mustn't take it as attached. I must've posted a completely wrong version from my experiments. Can't check, as the machine it's on is out of action with dead hardware:-( It's 3 in the morning again, but I've written an updated patch, This time I've adapted the testsuite to watch it in action and successfully run it (Linux 2.4.x). As ever, more eyes better:-) --- testreslist.c.old 2004-03-15 02:04:21.000000000 +0000 +++ testreslist.c 2004-03-15 02:55:18.000000000 +0000 @@ -98,7 +98,8 @@ res = apr_palloc(pool, sizeof(*res)); res->id = my_params->c_count++; - printf("++ constructing new resource [id:%d]\n", res->id); + printf("++ constructing new resource [id:%d, #%d/%d]\n", res->id, + my_params->c_count, my_params->d_count); /* Sleep for awhile, to simulate construction overhead. */ apr_sleep(my_params->sleep_upon_construct); @@ -114,8 +115,8 @@ my_resource_t *res = resource; my_parameters_t *my_params = params; - printf("-- destructing old resource [id:%d, #%d]\n", res->id, - my_params->d_count++); + printf("-- destructing old resource [id:%d, #%d/%d]\n", res->id, + my_params->c_count, ++my_params->d_count); apr_sleep(my_params->sleep_upon_destruct); @@ -147,12 +148,23 @@ printf(" [tid:%d,iter:%d] using resource id:%d\n", thread_info->tid, i, res->id); apr_sleep(thread_info->work_delay_sleep); - rv = apr_reslist_release(rl, res); - if (rv != APR_SUCCESS) { - fprintf(stderr, "Failed to return resource to reslist\n"); - apr_thread_exit(thd, rv); - return NULL; - } +/* simulate a 5% chance of the resource being bad */ + if ( drand48() < 0.95 ) { + rv = apr_reslist_release(rl, res); + if (rv != APR_SUCCESS) { + fprintf(stderr, "Failed to return resource to reslist\n"); + apr_thread_exit(thd, rv); + return NULL; + } + } else { + printf("invalidating resource id:%d\n", res->id) ; + rv = apr_reslist_invalidate(rl, res); + if (rv != APR_SUCCESS) { + fprintf(stderr, "Failed to invalidate resource\n"); + apr_thread_exit(thd, rv); + return NULL; + } + } } return APR_SUCCESS; @@ -167,6 +179,7 @@ int i; apr_thread_t *my_threads[CONSUMER_THREADS]; my_thread_info_t my_thread_info[CONSUMER_THREADS]; + srand48(time(0)) ; printf("Creating child pool......................."); rv = apr_pool_create(&pool, parpool); --- apr_reslist.h.old 2004-03-15 01:21:22.000000000 +0000 +++ apr_reslist.h 2004-03-15 01:31:01.000000000 +0000 @@ -150,6 +150,15 @@ APU_DECLARE(apr_status_t) apr_reslist_release(apr_reslist_t *reslist, void *resource); +/** + * Invalidate a resource in the pool - e.g. a database connection + * that returns a "lost connection" error and can't be restored. + * Use this instead of apr_reslist_release if the resource is bad. + */ +APU_DECLARE(apr_status_t) apr_reslist_invalidate(apr_reslist_t *reslist, + void *resource); + + #ifdef __cplusplus } #endif --- apr_reslist.c.old 2004-03-15 01:22:05.000000000 +0000 +++ apr_reslist.c 2004-03-15 01:28:56.000000000 +0000 @@ -396,5 +396,15 @@ return reslist_maint(reslist); } +APU_DECLARE(apr_status_t) apr_reslist_invalidate(apr_reslist_t *reslist, + void *resource) +{ + apr_status_t ret ; + apr_thread_mutex_lock(reslist->listlock); + ret = reslist->destructor(resource, reslist->params, reslist->pool); + --reslist->ntotal ; + apr_thread_mutex_unlock(reslist->listlock); + return ret ; +} #endif /* APR_HAS_THREADS */