13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**************************************************************************
23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * All Rights Reserved.
53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * copy of this software and associated documentation files (the
83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * "Software"), to deal in the Software without restriction, including
93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * permit persons to whom the Software is furnished to do so, subject to
123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * the following conditions:
133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The above copyright notice and this permission notice (including the
153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * next paragraph) shall be included in all copies or substantial portions
163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * of the Software.
173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org **************************************************************************/
273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * @file
303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Generic handle table implementation.
313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * @author José Fonseca <jrfonseca@tungstengraphics.com>
333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "pipe/p_compiler.h"
373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_debug.h"
383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_memory.h"
403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_handle_table.h"
413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#define HANDLE_TABLE_INITIAL_SIZE 16
443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct handle_table
473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /** Object array. Empty handles have a null object */
493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void **objects;
503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /** Number of objects the handle can currently hold */
523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned size;
533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /** Number of consecutive objects allocated at the start of the table */
543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned filled;
553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /** Optional object destructor */
573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void (*destroy)(void *object);
583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org};
593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct handle_table *
623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_create(void)
633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct handle_table *ht;
653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht = MALLOC_STRUCT(handle_table);
673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!ht)
683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return NULL;
693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *));
713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!ht->objects) {
723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      FREE(ht);
733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return NULL;
743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->size = HANDLE_TABLE_INITIAL_SIZE;
773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->filled = 0;
783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->destroy = NULL;
803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return ht;
823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid
863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_set_destroy(struct handle_table *ht,
873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                         void (*destroy)(void *object))
883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (!ht)
913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->destroy = destroy;
933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Resize the table if necessary
983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic INLINE int
1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_resize(struct handle_table *ht,
1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                    unsigned minimum_size)
1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned new_size;
1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void **new_objects;
1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(ht->size > minimum_size)
1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return ht->size;
1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   new_size = ht->size;
1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   while(!(new_size > minimum_size))
1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      new_size *= 2;
1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(new_size);
1133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   new_objects = (void **)REALLOC((void *)ht->objects,
1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org				  ht->size*sizeof(void *),
1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org				  new_size*sizeof(void *));
1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!new_objects)
1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->size = new_size;
1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->objects = new_objects;
1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return ht->size;
1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic INLINE void
1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_clear(struct handle_table *ht,
1313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                   unsigned index)
1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void *object;
1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* The order here is important so that the object being destroyed is not
1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org    * present in the table when seen by the destroy callback, because the
1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org    * destroy callback may directly or indirectly call the other functions in
1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org    * this module.
1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org    */
1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   object = ht->objects[index];
1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(object) {
1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      ht->objects[index] = NULL;
1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if(ht->destroy)
1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         ht->destroy(object);
1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgunsigned
1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_add(struct handle_table *ht,
1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                 void *object)
1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned index;
1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned handle;
1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(object);
1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!object || !ht)
1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* linear search for an empty handle */
1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   while(ht->filled < ht->size) {
1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if(!ht->objects[ht->filled])
1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 break;
1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      ++ht->filled;
1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   index = ht->filled;
1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   handle = index + 1;
1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* check integer overflow */
1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle)
1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* grow the table if necessary */
1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle_table_resize(ht, index))
1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
1803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(!ht->objects[index]);
1823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->objects[index] = object;
1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ++ht->filled;
1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return handle;
1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgunsigned
1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_set(struct handle_table *ht,
1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                 unsigned handle,
1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                 void *object)
1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned index;
1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(handle);
1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle || !ht)
1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(object);
2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!object)
2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   index = handle - 1;
2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* grow the table if necessary */
2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle_table_resize(ht, index))
2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return 0;
2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   handle_table_clear(ht, index);
2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   ht->objects[index] = object;
2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return handle;
2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid *
2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_get(struct handle_table *ht,
2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                 unsigned handle)
2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void *object;
2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(handle);
2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle || !ht || handle > ht->size)
2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return NULL;
2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   object = ht->objects[handle - 1];
2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return object;
2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid
2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_remove(struct handle_table *ht,
2383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                    unsigned handle)
2393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   void *object;
2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned index;
2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(handle);
2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!handle || !ht || handle > ht->size)
2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   index = handle - 1;
2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   object = ht->objects[index];
2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(!object)
2513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
2523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   handle_table_clear(ht, index);
2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(index < ht->filled)
2563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      ht->filled = index;
2573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgunsigned
2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_get_next_handle(struct handle_table *ht,
2623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                             unsigned handle)
2633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned index;
2653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for(index = handle; index < ht->size; ++index) {
2673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if(ht->objects[index])
2683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 return index + 1;
2693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
2703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return 0;
2723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgunsigned
2763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_get_first_handle(struct handle_table *ht)
2773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return handle_table_get_next_handle(ht, 0);
2793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgvoid
2833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orghandle_table_destroy(struct handle_table *ht)
2843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   unsigned index;
2863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   assert(ht);
2873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (!ht)
2893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      return;
2903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if(ht->destroy)
2923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      for(index = 0; index < ht->size; ++index)
2933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         handle_table_clear(ht, index);
2943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   FREE(ht->objects);
2963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   FREE(ht);
2973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
299