mesa: Prevent repeated glDeleteShader() from blowing away our refcounts.
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 19 Jul 2012 20:41:34 +0000 (13:41 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Sun, 22 Jul 2012 21:34:44 +0000 (14:34 -0700)
Calling glDeleteShader() should mark shaders as pending for deletion,
but shouldn't decrement the refcount every time.  Otherwise, repeated
glDeleteShader() is not safe.

This is particularly bad since glDeleteProgram() frees shaders: if you
first call glDeleteShader() on the shaders attached to the program (thus
decrementing the refcount), then called glDeleteProgram(), it would try
to free them again (decrementing the refcount another time), causing
a refcount > 0 assertion to fail.

Similar to commit d950a778.

NOTE: This is a candidate for the 8.0 branch.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/shaderapi.c

index 6927368de407be686c7923b6d540df1de23ccdc5..7c97a63593f5f0cc52debe0d1a54213cca13fa1d 100644 (file)
@@ -346,10 +346,12 @@ delete_shader(struct gl_context *ctx, GLuint shader)
    if (!sh)
       return;
 
-   sh->DeletePending = GL_TRUE;
+   if (!sh->DeletePending) {
+      sh->DeletePending = GL_TRUE;
 
-   /* effectively, decr sh's refcount */
-   _mesa_reference_shader(ctx, &sh, NULL);
+      /* effectively, decr sh's refcount */
+      _mesa_reference_shader(ctx, &sh, NULL);
+   }
 }