summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--include/apr_reslist.h20
-rw-r--r--util-misc/apr_reslist.c39
3 files changed, 53 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index ae24bb443..fdd532e2a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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)
{