summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorMathias Fröhlich <[email protected]>2011-10-22 12:57:01 +0200
committerBrian Paul <[email protected]>2011-10-24 08:37:19 -0600
commit9ed88983b03114d66d527354248e26f77d8868b9 (patch)
tree87d2a36ceae8b8cc570ece7fef3b2802d83b6aa2 /src/mesa/main
parentc9bb1bdc4859af001f0bc9a931eaf53266b49c0c (diff)
mesa: Avoid ABA problem on buffer object bind.
Make sure we do not run into the classic ABA problem on buffer object bind, reusing this name and may be never rebind since we get an new name that was just deleted and never rebound in between. The explicit rebinding to the debault object in the current context prevents the above in the current context, but another context sharing the same objects might suffer from this problem. Minor var renaming and comments edited by Brian. Signed-off-by: Mathias Fröhlich <[email protected]> Signed-off-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/bufferobj.c13
-rw-r--r--src/mesa/main/mtypes.h1
2 files changed, 13 insertions, 1 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 431eafd3879..4c77397d9dc 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -571,7 +571,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
/* Get pointer to old buffer object (to be unbound) */
oldBufObj = *bindTarget;
- if (oldBufObj && oldBufObj->Name == buffer)
+ if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending)
return; /* rebinding the same buffer object- no change */
/*
@@ -773,6 +773,17 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
/* The ID is immediately freed for re-use */
_mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]);
+ /* Make sure we do not run into the classic ABA problem on bind.
+ * We don't want to allow re-binding a buffer object that's been
+ * "deleted" by glDeleteBuffers().
+ *
+ * The explicit rebinding to the default object in the current context
+ * prevents the above in the current context, but another context
+ * sharing the same objects might suffer from this problem.
+ * The alternative would be to do the hash lookup in any case on bind
+ * which would introduce more runtime overhead than this.
+ */
+ bufObj->DeletePending = GL_TRUE;
_mesa_reference_buffer_object(ctx, &bufObj, NULL);
}
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d02bc167643..719dff3af2e 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1530,6 +1530,7 @@ struct gl_buffer_object
GLintptr Offset; /**< Mapped offset */
GLsizeiptr Length; /**< Mapped length */
/*@}*/
+ GLboolean DeletePending; /**< true if buffer object is removed from the hash */
GLboolean Written; /**< Ever written to? (for debugging) */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
};