From da10065d2b9b78fcb9446a4626343352cf30add0 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 26 Jul 2017 11:11:00 +1000 Subject: [PATCH] mesa: add NULL checking to free_shared_state() This will allow us to call this function from _mesa_alloc_shared_state() in the case that we run out of memory part way through allocating the state. Reviewed-by: Samuel Pitoiset --- src/mesa/main/shared.c | 90 ++++++++++++++++++++++----------- src/mesa/main/texturebindless.c | 8 ++- 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 2cce47e2268..a2f0f8d398c 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -334,46 +334,73 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) /* * Free display lists */ - _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx); - _mesa_DeleteHashTable(shared->DisplayList); - _mesa_HashDeleteAll(shared->BitmapAtlas, delete_bitmap_atlas_cb, ctx); - _mesa_DeleteHashTable(shared->BitmapAtlas); + if (shared->DisplayList) { + _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx); + _mesa_DeleteHashTable(shared->DisplayList); + } - _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx); - _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx); - _mesa_DeleteHashTable(shared->ShaderObjects); + if (shared->BitmapAtlas) { + _mesa_HashDeleteAll(shared->BitmapAtlas, delete_bitmap_atlas_cb, ctx); + _mesa_DeleteHashTable(shared->BitmapAtlas); + } - _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx); - _mesa_DeleteHashTable(shared->Programs); + if (shared->ShaderObjects) { + _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx); + _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx); + _mesa_DeleteHashTable(shared->ShaderObjects); + } - _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL); - _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL); + if (shared->Programs) { + _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx); + _mesa_DeleteHashTable(shared->Programs); + } - _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx); - _mesa_DeleteHashTable(shared->ATIShaders); - _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader); + if (shared->DefaultVertexProgram) + _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL); - _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx); - _mesa_DeleteHashTable(shared->BufferObjects); + if (shared->DefaultFragmentProgram) + _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL); - _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx); - _mesa_DeleteHashTable(shared->FrameBuffers); - _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx); - _mesa_DeleteHashTable(shared->RenderBuffers); + if (shared->DefaultFragmentShader) + _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader); - _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL); + if (shared->ATIShaders) { + _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx); + _mesa_DeleteHashTable(shared->ATIShaders); + } - { + if (shared->BufferObjects) { + _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx); + _mesa_DeleteHashTable(shared->BufferObjects); + } + + if (shared->FrameBuffers) { + _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx); + _mesa_DeleteHashTable(shared->FrameBuffers); + } + + if (shared->RenderBuffers) { + _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx); + _mesa_DeleteHashTable(shared->RenderBuffers); + } + + if (shared->NullBufferObj) + _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL); + + if (shared->SyncObjects) { struct set_entry *entry; - set_foreach(shared->SyncObjects, entry) { _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1); } - } - _mesa_set_destroy(shared->SyncObjects, NULL); - _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb, ctx); - _mesa_DeleteHashTable(shared->SamplerObjects); + _mesa_set_destroy(shared->SyncObjects, NULL); + } + + if (shared->SamplerObjects) { + _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb, + ctx); + _mesa_DeleteHashTable(shared->SamplerObjects); + } /* * Free texture objects (after FBOs since some textures might have @@ -382,12 +409,15 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) assert(ctx->Driver.DeleteTexture); /* the default textures */ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { - ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]); + if (shared->DefaultTex[i]) + ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]); } /* all other textures */ - _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx); - _mesa_DeleteHashTable(shared->TexObjects); + if (shared->TexObjects) { + _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx); + _mesa_DeleteHashTable(shared->TexObjects); + } _mesa_free_shared_handles(shared); diff --git a/src/mesa/main/texturebindless.c b/src/mesa/main/texturebindless.c index cb95ed07c5a..f062ea904a1 100644 --- a/src/mesa/main/texturebindless.c +++ b/src/mesa/main/texturebindless.c @@ -394,8 +394,12 @@ _mesa_init_shared_handles(struct gl_shared_state *shared) void _mesa_free_shared_handles(struct gl_shared_state *shared) { - _mesa_hash_table_u64_destroy(shared->TextureHandles, NULL); - _mesa_hash_table_u64_destroy(shared->ImageHandles, NULL); + if (shared->TextureHandles) + _mesa_hash_table_u64_destroy(shared->TextureHandles, NULL); + + if (shared->ImageHandles) + _mesa_hash_table_u64_destroy(shared->ImageHandles, NULL); + mtx_destroy(&shared->HandlesMutex); }