diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c index 4f06ce2cda4..9ad89b23f60 100644 --- a/src/mesa/main/hash.c +++ b/src/mesa/main/hash.c @@ -104,19 +104,23 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table) free(table); } -void -_mesa_HashEnableNameReuse(struct _mesa_HashTable *table) +static void init_name_reuse(struct _mesa_HashTable *table) { - _mesa_HashLockMutex(table); assert(_mesa_hash_table_num_entries(table->ht) == 0); table->id_alloc = MALLOC_STRUCT(util_idalloc); util_idalloc_init(table->id_alloc); util_idalloc_resize(table->id_alloc, 8); ASSERTED GLuint reserve0 = util_idalloc_alloc(table->id_alloc); assert (reserve0 == 0); - _mesa_HashUnlockMutex(table); } +void +_mesa_HashEnableNameReuse(struct _mesa_HashTable *table) +{ + _mesa_HashLockMutex(table); + init_name_reuse(table); + _mesa_HashUnlockMutex(table); +} /** * Lookup an entry in the hash table, without locking. @@ -327,7 +331,7 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table, if (table->id_alloc) { util_idalloc_fini(table->id_alloc); free(table->id_alloc); - _mesa_HashEnableNameReuse(table); + init_name_reuse(table); } table->MaxKey = 0; _mesa_HashUnlockMutex(table); diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index ded74d1ec45..3a3483c0182 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -55,9 +55,9 @@ * if refcount hits zero). * Then set ptr to point to sh, incrementing its refcount. */ -void -_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, - struct gl_shader *sh) +static void +_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, + struct gl_shader *sh, bool skip_locking) { assert(ptr); if (*ptr == sh) { @@ -71,8 +71,12 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, assert(old->RefCount > 0); if (p_atomic_dec_zero(&old->RefCount)) { - if (old->Name != 0) - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + if (old->Name != 0) { + if (skip_locking) + _mesa_HashRemoveLocked(ctx->Shared->ShaderObjects, old->Name); + else + _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + } _mesa_delete_shader(ctx, old); } @@ -87,6 +91,13 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, } } +void +_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, + struct gl_shader *sh) +{ + _reference_shader(ctx, ptr, sh, false); +} + static void _mesa_init_shader(struct gl_shader *shader) { @@ -252,9 +263,11 @@ _mesa_reference_shader_program_(struct gl_context *ctx, assert(old->RefCount > 0); if (p_atomic_dec_zero(&old->RefCount)) { - if (old->Name != 0) - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + _mesa_HashLockMutex(ctx->Shared->ShaderObjects); + if (old->Name != 0) + _mesa_HashRemoveLocked(ctx->Shared->ShaderObjects, old->Name); _mesa_delete_shader_program(ctx, old); + _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); } *ptr = NULL; @@ -356,6 +369,7 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, /** * Free all the data that hangs off a shader program object, but not the * object itself. + * Must be called with shared->ShaderObjects locked. */ void _mesa_free_shader_program_data(struct gl_context *ctx, @@ -384,7 +398,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, /* detach shaders */ for (i = 0; i < shProg->NumShaders; i++) { - _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); + _reference_shader(ctx, &shProg->Shaders[i], NULL, true); } shProg->NumShaders = 0;