util: Move u_debug to utils
[mesa.git] / src / gallium / auxiliary / util / u_handle_table.c
index 2176a009592f67defa3f66678ce1a24893a0448e..c6eeeef0f3a9f5a2a01e3588ce8c72896b2567ae 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * @file
  * Generic handle table implementation.
  *  
- * @author José Fonseca <jrfonseca@tungstengraphics.com>
+ * @author José Fonseca <jfonseca@vmware.com>
  */
 
 
 #include "pipe/p_compiler.h"
-#include "pipe/p_debug.h"
-#include "pipe/p_util.h"
+#include "util/u_debug.h"
 
-#include "u_handle_table.h"
+#include "util/u_memory.h"
+#include "util/u_handle_table.h"
 
 
 #define HANDLE_TABLE_INITIAL_SIZE 16  
@@ -64,7 +64,7 @@ handle_table_create(void)
    struct handle_table *ht;
    
    ht = MALLOC_STRUCT(handle_table);
-   if(!ht)
+   if (!ht)
       return NULL;
    
    ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *));
@@ -87,6 +87,8 @@ handle_table_set_destroy(struct handle_table *ht,
                          void (*destroy)(void *object))
 {
    assert(ht);
+   if (!ht)
+      return;
    ht->destroy = destroy;
 }
 
@@ -94,7 +96,7 @@ handle_table_set_destroy(struct handle_table *ht,
 /**
  * Resize the table if necessary 
  */
-static INLINE int
+static inline int
 handle_table_resize(struct handle_table *ht,
                     unsigned minimum_size)
 {
@@ -112,7 +114,7 @@ handle_table_resize(struct handle_table *ht,
    new_objects = (void **)REALLOC((void *)ht->objects,
                                  ht->size*sizeof(void *),
                                  new_size*sizeof(void *));
-   if(!new_objects)
+   if (!new_objects)
       return 0;
    
    memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *));
@@ -124,6 +126,28 @@ handle_table_resize(struct handle_table *ht,
 }
 
 
+static inline void
+handle_table_clear(struct handle_table *ht, 
+                   unsigned index)
+{
+   void *object;
+   
+   /* The order here is important so that the object being destroyed is not
+    * present in the table when seen by the destroy callback, because the 
+    * destroy callback may directly or indirectly call the other functions in 
+    * this module.
+    */
+
+   object = ht->objects[index];
+   if (object) {
+      ht->objects[index] = NULL;
+      
+      if(ht->destroy)
+         ht->destroy(object);
+   }   
+}
+
+
 unsigned
 handle_table_add(struct handle_table *ht, 
                  void *object)
@@ -133,7 +157,7 @@ handle_table_add(struct handle_table *ht,
    
    assert(ht);
    assert(object);
-   if(!object)
+   if(!object || !ht)
       return 0;
 
    /* linear search for an empty handle */
@@ -171,11 +195,11 @@ handle_table_set(struct handle_table *ht,
    
    assert(ht);
    assert(handle);
-   if(!handle)
+   if(!handle || !ht)
       return 0;
 
    assert(object);
-   if(!object)
+   if (!object)
       return 0;
    
    index = handle - 1;
@@ -184,9 +208,8 @@ handle_table_set(struct handle_table *ht,
    if(!handle_table_resize(ht, index))
       return 0;
 
-   if(ht->objects[index] && ht->destroy)
-      ht->destroy(ht->objects[index]);
-      
+   handle_table_clear(ht, index);
+
    ht->objects[index] = object;
    
    return handle;
@@ -201,7 +224,7 @@ handle_table_get(struct handle_table *ht,
    
    assert(ht);
    assert(handle);
-   if(!handle || handle > ht->size)
+   if(!handle || !ht || handle > ht->size)
       return NULL;
 
    object = ht->objects[handle - 1];
@@ -219,18 +242,16 @@ handle_table_remove(struct handle_table *ht,
    
    assert(ht);
    assert(handle);
-   if(!handle || handle > ht->size)
+   if(!handle || !ht || handle > ht->size)
       return;
 
    index = handle - 1;
    object = ht->objects[index];
-   if(!object)
+   if (!object)
       return;
    
-   if(ht->destroy)
-      ht->destroy(object);
+   handle_table_clear(ht, index);
 
-   ht->objects[index] = NULL;
    if(index < ht->filled)
       ht->filled = index;
 }
@@ -264,10 +285,12 @@ handle_table_destroy(struct handle_table *ht)
    unsigned index;
    assert(ht);
 
+   if (!ht)
+      return;
+
    if(ht->destroy)
       for(index = 0; index < ht->size; ++index)
-        if(ht->objects[index])
-           ht->destroy(ht->objects[index]);
+         handle_table_clear(ht, index);
    
    FREE(ht->objects);
    FREE(ht);