apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pier Fumagalli <p...@betaversion.org>
Subject Re: [PATCH] new Resource List interface for apr-util
Date Sat, 03 Aug 2002 19:57:12 GMT
It looks great... The only "nitpick" I might have to make (forgot to tell
you earlier) is that instead of apr_reslist_get and apr_reslist_put, those
should be called apr_reslist_acquire and apr_reslist_release, like in locks,
because this is what we do (we acquire a resource, locking it intrinsically,
and release it after we're done with it).

Get and put (especially put) seems to imply that I can create a resource,
and put it in the list, while we want to use the constructor and destructor
functions... :)

    Pier

"Aaron Bannert" <aaron@clove.org> wrote:

> Inspired by Pier and others, and motivated by the desire for a generic
> interface, I have created a Resource List API for threadsafe management of
> a group of reusable resources. It has attributes to control the minimum
> and maximum numbers of available resources, as well as a hard maximum
> on the total number and an expiration time (to prevent thrashing).
> 
> Take this example: A pool of database connections (not a memory pool,
> which is why I went with "apr_reslist_t" :):  Let's say we want to have
> at least 2 connections available at all times, at most 10 but to allow
> more than 10 if they were used within the last minute, and to never
> allow more than 25 total. Here's how we'd set it up:
> 
> /* Creation and destruction routines for my database connections */
> apr_status_t my_connection_constructor(void **my_conn, void *params,
>                                      apr_pool_t *pool);
> apr_status_t my_connection_destructor(void *my_conn, void *params,
>                                     apr_pool_t *pool);
> 
> 
> apr_reslist_create(&my_reslist, 2, 10, 25, 1*APR_USEC_PER_SEC,
>                  my_connection_constructor, my_connection_destructor,
>                  params, pool);
> 
> 
> 
> /* Then any number of threads can do this kind of thing to use it: */
> 
> apr_reslist_get(my_reslist, (void**)&a_connection);
> 
> 
> /* Here we would do something with the connection and then later when
> * we're done we return it to the list like so: */
> 
> apr_reslist_put(my_reslist, a_connection);
> 
> 
> That's all there is to it (with a little handwaving in the constructor/
> destructor part, but you all get the picture).
> 
> Let me know what you all think,
> -aaron
> 
> 
> /* ====================================================================
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> * modification, are permitted provided that the following conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> *    notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the above copyright
> *    notice, this list of conditions and the following disclaimer in
> *    the documentation and/or other materials provided with the
> *    distribution.
> *
> * 3. The end-user documentation included with the redistribution,
> *    if any, must include the following acknowledgment:
> *       "This product includes software developed by the
> *        Apache Software Foundation (http://www.apache.org/)."
> *    Alternately, this acknowledgment may appear in the software itself,
> *    if and wherever such third-party acknowledgments normally appear.
> *
> * 4. The names "Apache" and "Apache Software Foundation" must
> *    not be used to endorse or promote products derived from this
> *    software without prior written permission. For written
> *    permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache",
> *    nor may "Apache" appear in their name, without prior written
> *    permission of the Apache Software Foundation.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> * SUCH DAMAGE.
> * ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation.  For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> */
> 
> #ifndef APR_RESLIST_H
> #define APR_RESLIST_H
> 
> /** 
> * @file apr_reslist.h
> * @brief APR Resource List Routines
> */
> 
> #include "apr.h"
> #include "apu.h"
> #include "apr_pools.h"
> #include "apr_errno.h"
> #include "apr_time.h"
> 
> #if APR_HAS_THREADS
> 
> /**
> * @defgroup APR_RMM Resource List Routines
> * @ingroup APR
> * @{
> */
> 
> #ifdef __cplusplus
> extern "C" {
> #endif /* __cplusplus */
> 
> /** Opaque resource list object */
> typedef struct apr_reslist_t apr_reslist_t;
> 
> /**
> * Generic prototypes for the constructor and destructor that
> * is called by the resource list any time it needs to create
> * or destroy a resource.
> */
> typedef apr_status_t (*apr_reslist_constructor)(void **resource, void *params,
>                                               apr_pool_t *pool);
> typedef apr_status_t (*apr_reslist_destructor)(void *resource, void *params,
>                                              apr_pool_t *pool);
> 
> /**
> * Create a new resource list with the following parameters:
> * @param reslist An address where the pointer to the new resource
> *                list will be stored.
> * @param pool The pool to use for local storage and management
> * @param min Allowed minimum number of available resources. Zero
> *            creates new resources only when needed.
> * @param smax Resources will be destroyed to meet this maximum
> *             restriction as they expire.
> * @param hmaxx Absolute maximum limit on the number of total resources.
> * @param expire If non-zero, sets the maximum amount of time a resource
> *               may be available while exceeding the soft limit.
> * @param con Constructor routine that is called to create a new resource.
> * @param de Destructor routine that is called to destroy an expired resource.
> * @param pool The pool from which to create this resoure list. Also the
> *             same pool that is passed to the constructor and destructor
> *             routines.
> */
> APU_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist,
>                                            int min, int smax, int hmax,
>                                            apr_interval_time_t ttl,
>                                            apr_reslist_constructor con,
>                                            apr_reslist_destructor de,
>                                            void *params,
>                                            apr_pool_t *pool);
> 
> /**
> * Destroy the given resource list and all resources controlled by
> * this list.
> * FIXME: Should this block until all resources become available,
> *        or maybe just destroy all the free ones, or maybe destroy
> *        them even though they might be in use by something else?
> * @param rmm The relocatable memory block to destroy
> */
> APU_DECLARE(apr_status_t) apr_reslist_destroy(apr_reslist_t *reslist);
> 
> /**
> * Retrieve a 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.
> */
> APU_DECLARE(apr_status_t) apr_reslist_get(apr_reslist_t *reslist,
>                                         void **resource);
> 
> /**
> * Return a resource back to the list of available resources.
> */
> APU_DECLARE(apr_status_t) apr_reslist_put(apr_reslist_t *reslist,
>                                         void *resource);
> 
> #ifdef __cplusplus
> }
> #endif
> 
> /** @} */
> 
> #endif  /* APR_HAS_THREADS */
> 
> #endif  /* ! APR_RESLIST_H */
> 
> 


Mime
View raw message