X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_handle_table.c;h=6da7353e259a92b565dbf6da3987d21bc0621d81;hb=a18e209edb5348eb167e9d7184597031bbbbe622;hp=5a731a6b9636cdd3d7dc37d8a77d02e6f4a3dd2a;hpb=85108e5f8f3fd1ace813cb6eac6e82af4a2e2c7a;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 5a731a6b963..6da7353e259 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -34,10 +34,10 @@ #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 @@ -124,6 +124,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) @@ -170,7 +192,7 @@ handle_table_set(struct handle_table *ht, unsigned index; assert(ht); - assert(handle > 0); + assert(handle); if(!handle) return 0; @@ -184,7 +206,8 @@ handle_table_set(struct handle_table *ht, if(!handle_table_resize(ht, index)) return 0; - assert(!ht->objects[index]); + handle_table_clear(ht, index); + ht->objects[index] = object; return handle; @@ -198,13 +221,11 @@ handle_table_get(struct handle_table *ht, void *object; assert(ht); - assert(handle > 0); - assert(handle <= ht->size); + assert(handle); if(!handle || handle > ht->size) return NULL; object = ht->objects[handle - 1]; - assert(object); return object; } @@ -218,23 +239,17 @@ handle_table_remove(struct handle_table *ht, unsigned index; assert(ht); - assert(handle > 0); - assert(handle <= ht->size); + assert(handle); if(!handle || handle > ht->size) return; index = handle - 1; object = ht->objects[index]; - if(!object) { - /* XXX: this warning may be noisy for legitimate use -- remove later */ - debug_warning("removing empty handle"); + 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; } @@ -270,8 +285,7 @@ handle_table_destroy(struct handle_table *ht) 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);