FreeBSD/contrib/subversion/subversion/libsvn_subr/object_pool.c
/* Actual implementation of svn_object_pool__insert.
 *
 * Requires external serialization on OBJECT_POOL.
 */
Actual implementation of svn_object_pool__insert.
Requires external serialization on OBJECT_POOL.
Actual implementation of svn_object_pool__insert . Requires external serialization on OBJECT_POOL .
static svn_error_t *
insert(void **object,
       svn_object_pool__t *object_pool,
       const svn_membuf_t *key,
       void *wrapper,
       void *baton,
       apr_pool_t *wrapper_pool,
       apr_pool_t *result_pool)
{
  object_ref_t *object_ref
    = apr_hash_get(object_pool->objects, key->data, key->size);
  if (object_ref)
    {
      svn_error_t *err = object_pool->setter(&object_ref->wrapper,
                                             wrapper, baton,
                                             object_ref->pool);
      if (err)
        {
          apr_hash_set(object_pool->objects, key->data, key->size, NULL);
          svn_atomic_dec(&object_pool->object_count);
          if (svn_atomic_read(&object_ref->ref_count) == 0)
            svn_atomic_dec(&object_pool->unused_count);
          svn_pool_destroy(wrapper_pool);
          return svn_error_trace(err);
        }
      svn_pool_destroy(wrapper_pool);
    }
  else
    {
      object_ref = apr_pcalloc(wrapper_pool, sizeof(*object_ref));
      object_ref->object_pool = object_pool;
      object_ref->wrapper = wrapper;
      object_ref->pool = wrapper_pool;
      svn_membuf__create(&object_ref->key, key->size, wrapper_pool);
      object_ref->key.size = key->size;
      memcpy(object_ref->key.data, key->data, key->size);
      apr_hash_set(object_pool->objects, object_ref->key.data,
                   object_ref->key.size, object_ref);
      svn_atomic_inc(&object_pool->object_count);
      svn_atomic_inc(&object_ref->object_pool->unused_count);
    }
  *object = object_pool->getter(object_ref->wrapper, baton, result_pool);
  add_object_ref(object_ref, result_pool);
  if (svn_atomic_read(&object_pool->unused_count) * 2
      > apr_hash_count(object_pool->objects) + 2)
    remove_unused_objects(object_pool);
  return SVN_NO_ERROR;
}
static svn_error_t * insert ( void * * object , svn_object_pool__t * object_pool , const svn_membuf_t * key , void * wrapper , void * baton , apr_pool_t * wrapper_pool , apr_pool_t * result_pool ) { object_ref_t * object_ref = apr_hash_get ( object_pool -> objects , key -> data , key -> size ) ; if ( object_ref ) { svn_error_t * err = object_pool -> setter ( & object_ref -> wrapper , wrapper , baton , object_ref -> pool ) ; if ( err ) { apr_hash_set ( object_pool -> objects , key -> data , key -> size , NULL ) ; svn_atomic_dec ( & object_pool -> object_count ) ; if ( svn_atomic_read ( & object_ref -> ref_count ) == 0 ) svn_atomic_dec ( & object_pool -> unused_count ) ; svn_pool_destroy ( wrapper_pool ) ; return svn_error_trace ( err ) ; } svn_pool_destroy ( wrapper_pool ) ; } else { object_ref = apr_pcalloc ( wrapper_pool , sizeof ( * object_ref ) ) ; object_ref -> object_pool = object_pool ; object_ref -> wrapper = wrapper ; object_ref -> pool = wrapper_pool ; svn_membuf__create ( & object_ref -> key , key -> size , wrapper_pool ) ; object_ref -> key . size = key -> size ; memcpy ( object_ref -> key . data , key -> data , key -> size ) ; apr_hash_set ( object_pool -> objects , object_ref -> key . data , object_ref -> key . size , object_ref ) ; svn_atomic_inc ( & object_pool -> object_count ) ; svn_atomic_inc ( & object_ref -> object_pool -> unused_count ) ; } * object = object_pool -> getter ( object_ref -> wrapper , baton , result_pool ) ; add_object_ref ( object_ref , result_pool ) ; if ( svn_atomic_read ( & object_pool -> unused_count ) * 2 > apr_hash_count ( object_pool -> objects ) + 2 ) remove_unused_objects ( object_pool ) ; return SVN_NO_ERROR ; }
Actual implementation of svn_object_pool__insert.
Actual implementation of svn_object_pool__insert .
/* entry already exists (e.g. race condition) */ /* if we had an issue in the setter, then OBJECT_REF is in an
           * unknown state now.  Keep it around for the current users
           * (i.e. don't clean the pool) but remove it from the list of
           * available ones.
           */ /* for the unlikely case that the object got created _and_
           * already released since we last checked: */ /* cleanup the new data as well because it's not safe to use
           * either.
           */ /* propagate error */ /* Destroy the new one and return a reference to the existing one
       * because the existing one may already have references on it.
       */ /* add new index entry */ /* the new entry is *not* in use yet.
       * add_object_ref will update counters again.
       */ /* return a reference to the object we just added */ /* limit memory usage */