apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dr...@apache.org
Subject cvs commit: apr/memory/unix apr_sms.c apr_sms_std.c apr_sms_tracking.c Makefile.in
Date Mon, 14 May 2001 23:01:28 GMT
dreid       01/05/14 16:01:27

  Modified:    memory/unix Makefile.in
  Added:       memory/unix apr_sms.c apr_sms_std.c apr_sms_tracking.c
  Log:
  Add the renamed memory files to APR.
  
  apr_sms.c used to be apr_memory_system.c
  apr_sms_std.c used to be apr_standard_memory_system.c
  apr_sms_tracking.c used to be apr_tracking_memory_system.c
  
  Alter Makefile.in to actually build the new files.
  
  Revision  Changes    Path
  1.3       +3 -3      apr/memory/unix/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apr/memory/unix/Makefile.in,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Makefile.in	2001/05/09 16:30:21	1.2
  +++ Makefile.in	2001/05/14 23:01:25	1.3
  @@ -1,7 +1,7 @@
   
  -TARGETS = apr_memory_system.lo \
  -          apr_tracking_memory_system.lo \
  -          apr_standard_memory_system.lo
  +TARGETS = apr_sms.lo \
  +          apr_sms_std.lo \
  +          apr_sms_tracking.lo
   
   # bring in rules.mk for standard functionality
   @INCLUDE_RULES@
  
  
  
  1.1                  apr/memory/unix/apr_sms.c
  
  Index: apr_sms.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 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/>.
   */
  
  /* This code kindly donated to APR by 
   *    Elrond  <elrond@samba-tng.org>
   *    Luke Kenneth Casson Leighton <lkcl@samba-tng.org>
   *    Sander Striker <striker@samba-tng.org>
   *
   * May 2001
   */
   
  #include "apr.h"
  #include "apr_general.h"
  #include "apr_memory_system.h"
  #include <stdlib.h>
  #include <assert.h>
  
  #include <memory.h> /* strikerXXX: had to add this for windows to stop 
                       * complaining, please autoconf the include stuff
                       */
  
  /*
   * private structure defenitions
   */
  struct apr_sms_cleanup
  {
      struct apr_sms_cleanup *next;
      void *data;
      apr_status_t (*cleanup_fn)(void *);
  };
  
  /* 
   * memory allocation functions
   */
  
  APR_DECLARE(void *) apr_sms_malloc(apr_sms_t *mem_sys,
                                     apr_size_t size)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys);
      assert(mem_sys->malloc_fn);
  #endif
  
      if (!mem_sys || !mem_sys->malloc_fn)
          return NULL;
  
      if (size == 0)
          return NULL;
  
      return mem_sys->malloc_fn(mem_sys, size);
  }
  
  APR_DECLARE(void *) apr_sms_calloc(apr_sms_t *mem_sys,
                                     apr_size_t size)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys);
      assert(mem_sys->malloc_fn);
      assert(mem_sys->calloc_fn);
  #endif
  
      if (size == 0)
          return NULL;
  
      if (mem_sys->calloc_fn == NULL){
          /* Assumption - if we don't have calloc we have
           * malloc, might be bogus...
           */
          void *mem = mem_sys->malloc_fn(mem_sys, size);
          memset(mem, '\0', size);
          return mem;
      } else
          return mem_sys->calloc_fn(mem_sys, size);
  }
  
  APR_DECLARE(void *) apr_sms_realloc(apr_sms_t *mem_sys, void *mem,
                                      apr_size_t size)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys);
      assert(mem_sys->realloc_fn);
  #endif
     
      if (mem == NULL)
          return apr_sms_malloc(mem_sys, size);
  
      if (size == 0)
      {
          apr_sms_free(mem_sys, mem);
          return NULL;
      }
  
      return mem_sys->realloc_fn(mem_sys, mem, size);
  }
  
  APR_DECLARE(apr_status_t) apr_sms_free(apr_sms_t *mem_sys,
                                         void *mem)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys->free_fn);
  #endif
  
      if (!mem_sys)
          return APR_EMEMSYS;
    
      if (mem == NULL)
          return APR_EINVAL;
  
      if (mem_sys->free_fn != NULL)
          return mem_sys->free_fn(mem_sys, mem);  
  
      return APR_SUCCESS;
  }
  
  /*
   * memory system functions
   */
  
  static int apr_sms_is_tracking(apr_sms_t *mem_sys)
  {
      /*
       * The presense of a reset function gives us the clue that this is a 
       * tracking memory system.
       */
      return mem_sys->reset_fn != NULL;
  }
  
  APR_DECLARE(apr_sms_t *) apr_sms_create(void *memory, 
                                          apr_sms_t *parent_mem_sys)
  {
      apr_sms_t *mem_sys;
  
      if (memory == NULL)
          return NULL;
  
      /* Just typecast it, and clear it */
      mem_sys = (apr_sms_t *)memory;
      memset(mem_sys, '\0', sizeof(apr_sms_t));
  
      /* Initialize the parent and accounting memory system pointers */
      mem_sys->parent_mem_sys = parent_mem_sys;
      mem_sys->accounting_mem_sys = mem_sys;
  
      if (parent_mem_sys != NULL)
      {
          if ((mem_sys->sibling_mem_sys = 
             parent_mem_sys->child_mem_sys) != NULL)
          {
              mem_sys->sibling_mem_sys->ref_mem_sys = 
                &mem_sys->sibling_mem_sys;
          }
          mem_sys->ref_mem_sys = 
            &parent_mem_sys->child_mem_sys;
          parent_mem_sys->child_mem_sys = mem_sys;
      }
      /* This seems a bit redundant, but we're not taking chances */
      else
      {
          mem_sys->ref_mem_sys = NULL;
          mem_sys->sibling_mem_sys = NULL;
          mem_sys->child_mem_sys = NULL;
      }
  
      return mem_sys;
  }
  
  #ifdef APR_MEMORY_ASSERT
  APR_DECLARE(void) apr_sms_assert(apr_sms_t *mem_sys)
  {
      apr_sms_t *parent;
  
      /*
       * A memory system without a malloc won't do us much good
       */
      assert(mem_sys->malloc_fn != NULL);
  
      /* 
       * Check to see if this is either a non-tracking or
       * a tracking memory system. It has to have at least a free
       * or destroy function. And to avoid half implementations
       * we require reset to be present when destroy is.
       */
      assert(mem_sys->free_fn != NULL ||
           (mem_sys->destroy_fn != NULL &&
            mem_sys->reset_fn != NULL));
  
      assert(mem_sys->destroy_fn == NULL ||
           mem_sys->reset_fn != NULL);
    
      assert(mem_sys->reset_fn == NULL ||
           mem_sys->destroy_fn != NULL);
  
      /*
       * Make sure all accounting memory dies with the memory system.
       * To be more specific, make sure the accounting memort system
       * is either the memory system itself or a direct child.
       */
      assert(mem_sys->accounting_mem_sys == mem_sys ||
  	 mem_sys->accounting_mem_sys->parent_mem_sys == 
  	   mem_sys);
  
      /*
       * A non-tracking memory system can be the child of
       * another non-tracking memory system if there are no
       * tracking ancestors, but in that specific case we issue a
       * warning.
       */
      if (mem_sys->parent_mem_sys == NULL)
          return;
  
      parent = mem_sys
      while (parent)
      {
          if (apr_sms_is_tracking(parent))
              return; /* Tracking memory system found, return satisfied ;-) */
  
          parent = parent->parent_mem_sys;
      }
  
      /* issue a warning: 
       * WARNING: A non-tracking memory system was created without a tracking 
       * parent.
       */
  }
  #endif /* APR_MEMORY_ASSERT */
  
  /*
   * LOCAL FUNCTION used in:
   *  - apr_sms_do_child_cleanups
   *  - apr_sms_reset
   *  - apr_sms_destroy
   *
   * Call all the cleanup routines registered with a memory system.
   */
  static void apr_sms_do_cleanups(apr_sms_t *mem_sys)
  {
      struct apr_sms_cleanup *cleanup;
  
      cleanup = mem_sys->cleanups;
      while (cleanup)
      {
          cleanup->cleanup_fn(cleanup->data);
          cleanup = cleanup->next;
      }
  }
  
  /*
   * LOCAL FUNCTION used in:
   *  - apr_sms_reset
   *  - apr_sms_destroy
   *
   * This not only calls do_cleanups, but also calls the pre_destroy(!)
   */
  static void apr_sms_do_child_cleanups(apr_sms_t *mem_sys)
  {
      if (mem_sys == NULL)
          return;
  
      mem_sys = mem_sys->child_mem_sys;
      while (mem_sys)
      {
          apr_sms_do_child_cleanups(mem_sys);
          apr_sms_do_cleanups(mem_sys);
  
          if (mem_sys->pre_destroy_fn != NULL)
              mem_sys->pre_destroy_fn(mem_sys);
  
          mem_sys = mem_sys->sibling_mem_sys;
      }
  }
  
  APR_DECLARE(apr_status_t) apr_sms_reset(apr_sms_t *mem_sys)
  {
      if (!mem_sys)
          return APR_EMEMSYS;
      if (!mem_sys->reset_fn)
          return APR_EINVAL; /* Not sure if this is right... */
  
      /* 
       * Run the cleanups of all child memory systems _including_
       * the accounting memory system.
       */
      apr_sms_do_child_cleanups(mem_sys);
  
      /* Run all cleanups, the memory will be freed by the reset */
      apr_sms_do_cleanups(mem_sys);
      mem_sys->cleanups = NULL;
  
      /* We don't have any child memory systems after the reset */
      mem_sys->child_mem_sys = NULL;
  
      /* Reset the accounting memory system to ourselves, any
       * child memory system _including_ the accounting memory
       * system will be destroyed by the reset 
       * strikerXXX: Maybe this should be the responsibility of
       *             the reset function(?).
       */
      mem_sys->accounting_mem_sys = mem_sys;
  
      /* Let the memory system handle the actual reset */
      return mem_sys->reset_fn(mem_sys);
  }
  
  APR_DECLARE(apr_status_t) apr_sms_destroy(apr_sms_t *mem_sys)
  {
      apr_sms_t *child_mem_sys;
      apr_sms_t *sibling_mem_sys;
      struct apr_sms_cleanup *cleanup;
      struct apr_sms_cleanup *next_cleanup;
  
      if (!mem_sys)
          return APR_EMEMSYS;
  
      if (apr_sms_is_tracking(mem_sys))
      {
          /* 
           * Run the cleanups of all child memory systems _including_
           * the accounting memory system.
           */
          apr_sms_do_child_cleanups(mem_sys);
  
          /* Run all cleanups, the memory will be freed by the destroy */
          apr_sms_do_cleanups(mem_sys);
      }
      else
      {
          if (mem_sys->accounting_mem_sys != mem_sys)
          {
              child_mem_sys = mem_sys->accounting_mem_sys;
  		    
              /* 
               * Remove the accounting memory system from the memory systems 
               * child list (we will explicitly destroy it later in this block).
               */
              if (child_mem_sys->sibling_mem_sys != NULL)
  	            child_mem_sys->sibling_mem_sys->ref_mem_sys =
  	              child_mem_sys->ref_mem_sys;
  
              *child_mem_sys->ref_mem_sys = 
              child_mem_sys->sibling_mem_sys;
  
              /* Set this fields so destroy will work */
              child_mem_sys->ref_mem_sys = NULL;
              child_mem_sys->sibling_mem_sys = NULL;
          }
  
          /* Visit all children and destroy them */
          child_mem_sys = mem_sys->child_mem_sys;
          while (child_mem_sys != NULL)
          {
              sibling_mem_sys = child_mem_sys->sibling_mem_sys;
              apr_sms_destroy(child_mem_sys);
              child_mem_sys = sibling_mem_sys;
          }
  
          /*
           * If the accounting memory system _is_ tracking, we also know that it is
           * not the memory system itself.
           */
          if (apr_sms_is_tracking(mem_sys->accounting_mem_sys))
          {
              /* 
               * Run all cleanups, the memory will be freed by the destroying of the
               * accounting memory system.
               */
              apr_sms_do_cleanups(mem_sys);
  
              /* Destroy the accounting memory system */
              apr_sms_destroy(mem_sys->accounting_mem_sys);
  
              /* 
               * Set the accounting memory system back to the parent memory system
               * just in case...
               */
              mem_sys->accounting_mem_sys = mem_sys;
          }
          else
          {
              /* Run all cleanups, free'ing memory as we go */
              cleanup = mem_sys->cleanups;
              while (cleanup)
              {
                  cleanup->cleanup_fn(cleanup->data);
                  next_cleanup = cleanup->next;
                  apr_sms_free(mem_sys->accounting_mem_sys, 
  			       cleanup);
                  cleanup = next_cleanup;
              }
  
              if (mem_sys->accounting_mem_sys != mem_sys)
              {
                  /* Destroy the accounting memory system */
                  apr_sms_destroy(mem_sys->accounting_mem_sys);
                  /* 
                   * Set the accounting memory system back to the parent memory system
                   * just in case...
                   */
                  mem_sys->accounting_mem_sys = mem_sys;
              }
         }
    }
  
    /* Remove the memory system from the parent memory systems child list */
    if (mem_sys->sibling_mem_sys != NULL)
        mem_sys->sibling_mem_sys->ref_mem_sys =
          mem_sys->ref_mem_sys;
    if (mem_sys->ref_mem_sys != NULL)
        *mem_sys->ref_mem_sys = mem_sys->sibling_mem_sys;
  
    /* Call the pre-destroy if present */
    if (mem_sys->pre_destroy_fn != NULL)
        mem_sys->pre_destroy_fn(mem_sys);
  
    /* 1 - If we have a self destruct, use it */
    if (mem_sys->destroy_fn != NULL)
        return mem_sys->destroy_fn(mem_sys);
  
    /* 2 - If we don't have a parent, free using ourselves */
    else if (mem_sys->parent_mem_sys == NULL)
        return mem_sys->free_fn(mem_sys, mem_sys);
  
    /* 3 - If we do have a parent and it has a free function, use it */
    else if (mem_sys->parent_mem_sys->free_fn != NULL)
        return apr_sms_free(mem_sys->parent_mem_sys, mem_sys);
  
    /* 4 - Assume we are the child of a tracking memory system, and do nothing */
  #ifdef APR_ASSERT_MEMORY
      mem_sys = mem_sys->parent_mem_sys;
      while (mem_sys)
      {
          if (apr_sms_is_tracking(mem_sys))
              return APR_SUCCESS;
  
          mem_sys = mem_sys->parent_mem_sys;
      }
      assert(0); /* Made the wrong assumption, so we assert */
  #endif /* APR_MEMORY_ASSERT */
      return APR_SUCCESS;
  }
  
  APR_DECLARE(apr_status_t) apr_sms_is_ancestor(apr_sms_t *a,
                                                apr_sms_t *b)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(a != NULL);
      assert(b != NULL);
  #endif
      if (!b)
          return APR_EINVAL;
          
      while (b && b != a)
          b = b->parent_mem_sys;
  
      /* APR_SUCCESS = 0, so if they agree we should return that... */
      return !(b == a); 
  }
  
  APR_DECLARE(void) apr_sms_threadsafe_lock(apr_sms_t *mem_sys)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys != NULL);
  #endif
  
      if (!mem_sys)
          return;       
      if (mem_sys->threadsafe_lock_fn != NULL)
          mem_sys->threadsafe_lock_fn(mem_sys);
  }
  
  APR_DECLARE(void) apr_sms_threadsafe_unlock(apr_sms_t *mem_sys)
  {
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys != NULL);
  #endif
  
      if (!mem_sys)
          return;
      if (mem_sys->threadsafe_unlock_fn != NULL)
          mem_sys->threadsafe_unlock_fn(mem_sys);
  }
  
  /*
   * memory system cleanup management functions
   */
  
  APR_DECLARE(apr_status_t) 
  apr_sms_cleanup_register(apr_sms_t *mem_sys, void *data,
                           apr_status_t (*cleanup_fn)(void *))
  {
      struct apr_sms_cleanup *cleanup;
  
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys->accounting_mem_sys != NULL);
  #endif
  
      if (!mem_sys)
          return APR_EMEMSYS;
      
      if (cleanup_fn == NULL)
          return APR_EINVAL;
  
      cleanup = (struct apr_sms_cleanup *)
  	    apr_sms_malloc(mem_sys->accounting_mem_sys,
                         sizeof(struct apr_sms_cleanup));
  
      if (cleanup == NULL)
          return APR_ENOMEM;
  
      cleanup->data = data;
      cleanup->cleanup_fn = cleanup_fn;
      cleanup->next = mem_sys->cleanups;
      mem_sys->cleanups = cleanup;
  
      return APR_SUCCESS;
  }
  
  APR_DECLARE(apr_status_t)
  apr_sms_cleanup_unregister(apr_sms_t *mem_sys, void *data,
                             apr_status_t (*cleanup_fn)(void *))
  {
      struct apr_sms_cleanup *cleanup;
      struct apr_sms_cleanup **cleanup_ref;
  
  #ifdef APR_ASSERT_MEMORY
      assert(mem_sys->accounting_mem_sys != NULL);
  #endif
  
      if (!mem_sys)
          return APR_EMEMSYS;
          
      cleanup = mem_sys->cleanups;
      cleanup_ref = &mem_sys->cleanups;
      while (cleanup)
      {
          if (cleanup->data == data && cleanup->cleanup_fn == cleanup_fn)
          {
              *cleanup_ref = cleanup->next;
  
              mem_sys = mem_sys->accounting_mem_sys;
  
              if (mem_sys->free_fn != NULL)
                  apr_sms_free(mem_sys, cleanup);
  
              return APR_SUCCESS;
          }
  
          cleanup_ref = &cleanup->next;
          cleanup = cleanup->next;
      }
  
      /* The cleanup function should have been registered previously */
      return APR_ENOCLEANUP;
  }
  
  APR_DECLARE(apr_status_t) 
  apr_sms_cleanup_run(apr_sms_t *mem_sys, void *data, 
  			        apr_status_t (*cleanup_fn)(void *))
  {
      apr_sms_cleanup_unregister(mem_sys, data, cleanup_fn);
      return cleanup_fn(data);
  }
  
  
  
  1.1                  apr/memory/unix/apr_sms_std.c
  
  Index: apr_sms_std.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 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/>.
   */
  
  /* This code kindly donated to APR by 
   *    Elrond  <elrond@samba-tng.org>
   *    Luke Kenneth Casson Leighton <lkcl@samba-tng.org>
   *    Sander Striker <striker@samba-tng.org>
   *
   * May 2001
   */
  
  #include "apr.h"
  #include "apr_private.h"
  #include "apr_memory_system.h"
  #include <stdlib.h>
  #include <assert.h>
  
  /*
   * standard memory system
   */
  
  static void * apr_sms_std_malloc(apr_sms_t *mem_sys,
                                   apr_size_t size)
  {
      return malloc(size);
  }
  
  static void * apr_sms_std_calloc(apr_sms_t *mem_sys,
                                   apr_size_t size)
  {
  #if HAVE_CALLOC
      return calloc(1, size);
  #else
      void *mem;
      mem = malloc(size);
      memset(mem, '\0', size);
      return mem;
  #endif
  }
  
  
  static void * apr_sms_std_realloc(apr_sms_t *mem_sys,
                                    void *mem, apr_size_t size)
  {
      return realloc(mem, size);
  }
  
  static apr_status_t apr_sms_std_free(apr_sms_t *mem_sys,
                                       void *mem)
  {
      free(mem);
      return APR_SUCCESS;
  }
  
  APR_DECLARE(apr_status_t) apr_sms_std_create(apr_sms_t **mem_sys)
  {
      apr_sms_t *new_mem_sys;
  
      assert(mem_sys != NULL);
  
      *mem_sys = NULL;
      /* should we be using apr_sms_calloc now we have it??? */
      new_mem_sys = apr_sms_create(malloc(sizeof(apr_sms_t)),
                                   NULL);
  
      if (new_mem_sys == NULL)
          return APR_ENOMEM;
  
      new_mem_sys->malloc_fn  = apr_sms_std_malloc;
      new_mem_sys->calloc_fn  = apr_sms_std_calloc;
      new_mem_sys->realloc_fn = apr_sms_std_realloc;
      new_mem_sys->free_fn    = apr_sms_std_free;
      /* as we're not a tracking memory module, i.e. we don't keep
       * track of our allocations, we don't have apr_sms_reset or
       * apr_sms_destroy functions.
       */
      apr_sms_assert(new_mem_sys);
  
      *mem_sys = new_mem_sys;
      return APR_SUCCESS;
  }
  
  
  
  1.1                  apr/memory/unix/apr_sms_tracking.c
  
  Index: apr_sms_tracking.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 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/>.
   */
  
  /* This code kindly donated to APR by 
   *    Elrond  <elrond@samba-tng.org>
   *    Luke Kenneth Casson Leighton <lkcl@samba-tng.org>
   *    Sander Striker <striker@samba-tng.org>
   *
   * May 2001
   */
  
  #include "apr.h"
  #include "apr_general.h"
  #include "apr_private.h"
  #include "apr_tracking_memory_system.h"
  #include <stdlib.h>
  #include <assert.h>
  
  /*
   * Simple tracking memory system
   */
  
  /* INTERNALLY USED STRUCTURES */
  typedef struct apr_track_node_t
  {
      struct apr_track_node_t  *next;
      struct apr_track_node_t **ref;
  } apr_track_node_t;
  
  typedef struct apr_sms_tracking_t
  {
      apr_sms_t            header;
      apr_track_node_t    *nodes;
  } apr_sms_tracking_t;
  
  static void * apr_sms_tracking_malloc(apr_sms_t *mem_sys,
                                        apr_size_t size)
  {
      apr_sms_tracking_t *tms;
      apr_track_node_t *node;
    
      assert (mem_sys != NULL);
  
      tms = (apr_sms_tracking_t *)mem_sys;
      node = apr_sms_malloc(mem_sys->parent_mem_sys,
                            size + sizeof(apr_track_node_t));
      if (node == NULL)
          return NULL;
  
      node->next = tms->nodes;
      tms->nodes = node;
      node->ref = &tms->nodes;
      if (node->next != NULL)
          node->next->ref = &node->next;
  
      node++;
  
      return (void *)node;
  }
  
  static  void * apr_sms_tracking_calloc(apr_sms_t *mem_sys, 
                                         apr_size_t size)
  {
      apr_sms_tracking_t *tms;
      apr_track_node_t *node;
    
      assert (mem_sys != NULL);
  
      tms = (apr_sms_tracking_t *)mem_sys;
      node = apr_sms_calloc(mem_sys->parent_mem_sys,
                            size + sizeof(apr_track_node_t));
      if (node == NULL)
          return NULL;
  
      node->next = tms->nodes;
      tms->nodes = node;
      node->ref = &tms->nodes;
      if (node->next != NULL)
          node->next->ref = &node->next;
  
      node++;
  
      return (void *)node;
  }
  
  static  void * apr_sms_tracking_realloc(apr_sms_t *mem_sys,
                                          void *mem, apr_size_t size)
  {
      apr_sms_tracking_t *tms;
      apr_track_node_t *node;
  
      assert (mem_sys != NULL);
  
      tms = (apr_sms_tracking_t *)mem_sys;
      node = (apr_track_node_t *)mem;
  
      if (node != NULL)
      {
          node--;
          *(node->ref) = node->next;
      }
  
      node = apr_sms_realloc(mem_sys->parent_mem_sys,
                             node, size + sizeof(apr_track_node_t));
      if (node == NULL)
          return NULL;
  
      node->next = tms->nodes;
      tms->nodes = node;
      node->ref = &tms->nodes;
      if (node->next != NULL)
          node->next->ref = &node->next;
  
      node++;
  
      return (void *)node;
  }
  
  static  apr_status_t apr_sms_tracking_free(apr_sms_t *mem_sys,
                                             void *mem)
  {
      apr_track_node_t *node;
  
      assert (mem_sys != NULL);
      assert (mem != NULL);
  
      node = (apr_track_node_t *)mem;
      node--;
  
      *(node->ref) = node->next;
      if (node->next != NULL)
          node->next->ref = node->ref;
            
      return apr_sms_free(mem_sys->parent_mem_sys, node);
  }
  
  static apr_status_t apr_sms_tracking_reset(apr_sms_t *mem_sys)
  {
      apr_sms_tracking_t *tms;
      apr_track_node_t *node;
      apr_status_t rv;
      
      assert (mem_sys != NULL);
  
      tms = (apr_sms_tracking_t *)mem_sys;
  
      while (tms->nodes != NULL)
      {
          node = tms->nodes;
          *(node->ref) = node->next;
          if (node->next != NULL)
              node->next->ref = node->ref;
          if ((rv = apr_sms_free(mem_sys->parent_mem_sys, 
                                 node)) != APR_SUCCESS)
              return rv;
      }
      return APR_SUCCESS;
  }
  
  static apr_status_t apr_sms_tracking_destroy(apr_sms_t *mem_sys)
  {
      apr_status_t rv;
      /* If this is NULL we won't blow up as it should be caught at the
       * next level down and then passed back to us...
       */
  #ifdef APR_ASSERT_MEMORY
      assert (mem_sys->parent_mem_sys != NULL);
  #endif
      
      if (!mem_sys)
          return APR_EMEMSYS;
  
      if ((rv = apr_sms_tracking_reset(mem_sys)) != APR_SUCCESS)
          return rv;
      return apr_sms_free(mem_sys->parent_mem_sys, mem_sys);
  }
  
  APR_DECLARE(apr_status_t) apr_sms_tracking_create(apr_sms_t **mem_sys, 
                                                    apr_sms_t *pms)
  {
      apr_sms_t *new_mem_sys, *tmpms;
      apr_sms_tracking_t *tms;
  
      assert (mem_sys != NULL);
      assert (pms != NULL);
      *mem_sys = NULL;
      /* changed this to 2 stages to make easier to follow...
       * should we be using apr_sms_calloc now we have it? 
       */
      tmpms = apr_sms_malloc(pms, sizeof(apr_sms_tracking_t));
      new_mem_sys = apr_sms_create(tmpms, pms);
  
      if (new_mem_sys == NULL)
          return APR_ENOMEM;
  
      new_mem_sys->malloc_fn  = apr_sms_tracking_malloc;
      new_mem_sys->calloc_fn  = apr_sms_tracking_calloc;
      new_mem_sys->realloc_fn = apr_sms_tracking_realloc;
      new_mem_sys->free_fn    = apr_sms_tracking_free;
      new_mem_sys->reset_fn   = apr_sms_tracking_reset;
      new_mem_sys->destroy_fn = apr_sms_tracking_destroy;
  
      tms = (apr_sms_tracking_t *)new_mem_sys;
      tms->nodes = NULL;
  
      apr_sms_assert(new_mem_sys);
  
      *mem_sys = new_mem_sys;
      return APR_SUCCESS;
  }
  
  
  

Mime
View raw message