diff options
author | Yann Ylavic <ylavic@apache.org> | 2018-06-21 17:37:31 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2018-06-21 17:37:31 +0000 |
commit | 3b184bb1f97b973487e13e95e8ab54fdb02e3e24 (patch) | |
tree | de1738f654826bfc84a4f84c8779fe02ae98add6 | |
parent | 22d813ce8f45111bd9bf2aee56295ccbba186d96 (diff) | |
download | apr-3b184bb1f97b973487e13e95e8ab54fdb02e3e24.tar.gz |
apr_reslist: add apr_reslist_acquire_ex().
Allows to control acquire order, either LIFO (default and current behaviour) or FIFO.
Associated test upcoming...
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1834034 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | include/apr_reslist.h | 20 | ||||
-rw-r--r-- | util-misc/apr_reslist.c | 39 |
3 files changed, 53 insertions, 9 deletions
@@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes for APR 2.0.0 + *) Add apr_reslist_acquire_ex() which allows to control acquire order, + that is LIFO (default) or FIFO. [Yann Ylavic] + *) apr_file_write: Optimize large reads from buffered files on Windows. [Evgeny Kotkov] diff --git a/include/apr_reslist.h b/include/apr_reslist.h index 4e09e12aa..85e525821 100644 --- a/include/apr_reslist.h +++ b/include/apr_reslist.h @@ -107,8 +107,26 @@ APR_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist, */ APR_DECLARE(apr_status_t) apr_reslist_destroy(apr_reslist_t *reslist); +/* Acquire order modes */ +#define APR_RESLIST_ACQUIRE_LIFO 0x0 +#define APR_RESLIST_ACQUIRE_FIFO 0x1 +#define APR_RESLIST_ACQUIRE_MASK 0x1 + +/** + * Retrieve a resource from the list, either the oldest (FIFO) or + * latest (LIFO), creating a new one if necessary. + * If we have met our maximum number of resources, we will block + * until one becomes available. + * @param reslist The resource list. + * @param resource An address where the pointer to the resource + * will be stored. + * @param flags Bitmask of APR_RESLIST_ACQUIRE_* flags. + */ +APR_DECLARE(apr_status_t) apr_reslist_acquire_ex(apr_reslist_t *reslist, + void **resource, int flags); + /** - * Retrieve a resource from the list, creating a new one if necessary. + * Retrieve the latest resource from the list, creating a new one if necessary. * If we have met our maximum number of resources, we will block * until one becomes available. * @param reslist The resource list. diff --git a/util-misc/apr_reslist.c b/util-misc/apr_reslist.c index 7b6ff3507..dadc3529a 100644 --- a/util-misc/apr_reslist.c +++ b/util-misc/apr_reslist.c @@ -61,13 +61,18 @@ struct apr_reslist_t { }; /** - * Grab a resource from the front of the resource list. + * Grab a resource from the resource list, latest or oldest depending on fifo. * Assumes: that the reslist is locked. */ -static apr_res_t *pop_resource(apr_reslist_t *reslist) +static apr_res_t *pop_resource(apr_reslist_t *reslist, int fifo) { apr_res_t *res; - res = APR_RING_FIRST(&reslist->avail_list); + if (fifo) { + res = APR_RING_LAST(&reslist->avail_list); + } + else { + res = APR_RING_FIRST(&reslist->avail_list); + } APR_RING_REMOVE(res, link); reslist->nidle--; return res; @@ -150,7 +155,7 @@ static apr_status_t reslist_cleanup(void *data_) while (rl->nidle > 0) { apr_status_t rv1; - res = pop_resource(rl); + res = pop_resource(rl, 0); rl->ntotal--; rv1 = destroy_resource(rl, res); if (rv1 != APR_SUCCESS) { @@ -329,11 +334,17 @@ APR_DECLARE(apr_status_t) apr_reslist_destroy(apr_reslist_t *reslist) return apr_pool_cleanup_run(reslist->pool, reslist, reslist_cleanup); } -APR_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, - void **resource) +static apr_status_t reslist_acquire(apr_reslist_t *reslist, + void **resource, int flags) { apr_status_t rv; apr_res_t *res; + int fifo; + + if (flags & ~APR_RESLIST_ACQUIRE_MASK) { + return APR_EINVAL; + } + fifo = flags & APR_RESLIST_ACQUIRE_FIFO; #if APR_HAS_THREADS apr_thread_mutex_lock(reslist->listlock); @@ -367,7 +378,7 @@ APR_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, } /* If there is still an idle resource, use it right away */ if (reslist->nidle > 0) { - res = pop_resource(reslist); + res = pop_resource(reslist, fifo); *resource = res->opaque; free_container(reslist, res); #if APR_HAS_THREADS @@ -396,7 +407,7 @@ APR_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, /* If we popped out of the loop, first try to see if there * are new resources available for immediate use. */ if (reslist->nidle > 0) { - res = pop_resource(reslist); + res = pop_resource(reslist, fifo); *resource = res->opaque; free_container(reslist, res); #if APR_HAS_THREADS @@ -421,6 +432,18 @@ APR_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, } } +APR_DECLARE(apr_status_t) apr_reslist_acquire_ex(apr_reslist_t *reslist, + void **resource, int flags) +{ + return reslist_acquire(reslist, resource, flags); +} + +APR_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, + void **resource) +{ + return reslist_acquire(reslist, resource, 0); +} + APR_DECLARE(apr_status_t) apr_reslist_release(apr_reslist_t *reslist, void *resource) { |