From a3a77fb2cb515be72de6eb36d51da40998a2d8a3 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Wed, 27 Jun 2018 23:18:10 +0000 Subject: [PATCH 08/15] Merge r1834022, r1834023, r1834024 from trunk: apr_reslist: test for ttl = 0 The current reslist implementation handles ttl=0 as no TTL when acquiring resources (expected and documented), but as zero TTL when releasing (immediate expiry, so resources above smax are never recycled). This test validates the upcoming fix (r1834023). apr_reslist: fix release of resource with zero/no TTL. Ignore expiry when ttl=0 in apr_reslist_maintain(), like apr_reslist_acquire(). While ttl=0 is supposed to mean no TTL/expiry, apr_reslist_maintain() hence apr_reslist_release() were destroying all resources above smax in this case. Corresponding test already committed in r1834022. apr_reslist: follow up to r1834023: avoid unnecessary apr_time_now() calls. When ttl=0 is configured, we never need to check for expiry. git-svn-id: https://svn.apache.org/repos/asf/apr/apr-util/branches/1.6.x@1834558 13f79535-47bb-0310-9956-ffa450edef68 --- misc/apr_reslist.c | 16 +++++++++++----- test/testreslist.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/misc/apr_reslist.c b/misc/apr_reslist.c index 0c43e074..12ae96a1 100644 --- a/misc/apr_reslist.c +++ b/misc/apr_reslist.c @@ -81,7 +81,9 @@ static apr_res_t *pop_resource(apr_reslist_t *reslist) static void push_resource(apr_reslist_t *reslist, apr_res_t *resource) { APR_RING_INSERT_HEAD(&reslist->avail_list, resource, apr_res_t, link); - resource->freed = apr_time_now(); + if (reslist->ttl) { + resource->freed = apr_time_now(); + } reslist->nidle++; } @@ -210,8 +212,10 @@ APU_DECLARE(apr_status_t) apr_reslist_maintain(apr_reslist_t *reslist) created_one++; } - /* We don't need to see if we're over the max if we were under it before */ - if (created_one) { + /* We don't need to see if we're over the max if we were under it before, + * nor need we check for expiry if no ttl is configure. + */ + if (created_one || !reslist->ttl) { #if APR_HAS_THREADS apr_thread_mutex_unlock(reslist->listlock); #endif @@ -328,14 +332,16 @@ APU_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, { apr_status_t rv; apr_res_t *res; - apr_time_t now; + apr_time_t now = 0; #if APR_HAS_THREADS apr_thread_mutex_lock(reslist->listlock); #endif /* If there are idle resources on the available list, use * them right away. */ - now = apr_time_now(); + if (reslist->ttl) { + now = apr_time_now(); + } while (reslist->nidle > 0) { /* Pop off the first resource */ res = pop_resource(reslist); diff --git a/test/testreslist.c b/test/testreslist.c index 36333a15..78c908d2 100644 --- a/test/testreslist.c +++ b/test/testreslist.c @@ -258,6 +258,44 @@ static void test_reslist(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } +static void test_reslist_no_ttl(abts_case *tc, void *data) +{ + apr_status_t rv; + apr_reslist_t *rl; + my_parameters_t *params; + my_resource_t *res; + + /* Parameters (sleep not used) */ + params = apr_pcalloc(p, sizeof(*params)); + + rv = apr_reslist_create(&rl, + /*no min*/0, /*no smax*/0, /*max*/1, /*no ttl*/0, + my_constructor, my_destructor, params, p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + /* Acquire/contruct one resource */ + rv = apr_reslist_acquire(rl, (void **)&res); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + ABTS_INT_EQUAL(tc, 0, res->id); + + /* Release it before next check */ + rv = apr_reslist_release(rl, res); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + /* Re-acquire/release: the resource should be the same */ + rv = apr_reslist_acquire(rl, (void **)&res); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + ABTS_INT_EQUAL(tc, 0, res->id); + + /* Release it before cleanup */ + rv = apr_reslist_release(rl, res); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_reslist_destroy(rl); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + ABTS_INT_EQUAL(tc, params->d_count, 1); +} + #endif /* APR_HAS_THREADS */ abts_suite *testreslist(abts_suite *suite) @@ -266,6 +304,7 @@ abts_suite *testreslist(abts_suite *suite) #if APR_HAS_THREADS abts_run_test(suite, test_reslist, NULL); + abts_run_test(suite, test_reslist_no_ttl, NULL); #endif return suite; -- 2.19.1