mesa: use new _mesa_reference_shared_state() function

This cleans up the reference counting of shared context state.
The next patch will use this to fix an actual bug.

NOTE: This is a candidate for the 8.0 branch.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
(cherry picked from commit 361cd53a77)
This commit is contained in:
Brian Paul 2012-01-31 18:23:03 -07:00 committed by Ian Romanick
parent f723df005c
commit 2ed8367d72
3 changed files with 48 additions and 37 deletions

View file

@ -939,13 +939,10 @@ _mesa_initialize_context(struct gl_context *ctx,
return GL_FALSE; return GL_FALSE;
} }
_glthread_LOCK_MUTEX(shared->Mutex); _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
ctx->Shared = shared;
shared->RefCount++;
_glthread_UNLOCK_MUTEX(shared->Mutex);
if (!init_attrib_groups( ctx )) { if (!init_attrib_groups( ctx )) {
_mesa_release_shared_state(ctx, ctx->Shared); _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
return GL_FALSE; return GL_FALSE;
} }
@ -973,7 +970,7 @@ _mesa_initialize_context(struct gl_context *ctx,
} }
if (!ctx->Exec) { if (!ctx->Exec) {
_mesa_release_shared_state(ctx, ctx->Shared); _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
return GL_FALSE; return GL_FALSE;
} }
#endif #endif
@ -1002,7 +999,7 @@ _mesa_initialize_context(struct gl_context *ctx,
#if FEATURE_dlist #if FEATURE_dlist
ctx->Save = _mesa_create_save_table(); ctx->Save = _mesa_create_save_table();
if (!ctx->Save) { if (!ctx->Save) {
_mesa_release_shared_state(ctx, ctx->Shared); _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
free(ctx->Exec); free(ctx->Exec);
return GL_FALSE; return GL_FALSE;
} }
@ -1140,7 +1137,7 @@ _mesa_free_context_data( struct gl_context *ctx )
free(ctx->Save); free(ctx->Save);
/* Shared context state (display lists, textures, etc) */ /* Shared context state (display lists, textures, etc) */
_mesa_release_shared_state( ctx, ctx->Shared ); _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
/* needs to be after freeing shared state */ /* needs to be after freeing shared state */
_mesa_free_display_list_data(ctx); _mesa_free_display_list_data(ctx);
@ -1540,17 +1537,18 @@ GLboolean
_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) _mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
{ {
if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
struct gl_shared_state *oldSharedState = ctx->Shared; struct gl_shared_state *oldShared = NULL;
ctx->Shared = ctxToShare->Shared; /* save ref to old state to prevent it from being deleted immediately */
_mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount++; /* update ctx's Shared pointer */
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
update_default_objects(ctx); update_default_objects(ctx);
_mesa_release_shared_state(ctx, oldSharedState); /* release the old shared state */
_mesa_reference_shared_state(ctx, &oldShared, NULL);
return GL_TRUE; return GL_TRUE;
} }

View file

@ -388,28 +388,40 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
/** /**
* Decrement shared state object reference count and potentially free it * gl_shared_state objects are ref counted.
* and all children structures. * If ptr's refcount goes to zero, free the shared state.
*
* \param ctx GL context.
* \param shared shared state pointer.
*
* \sa free_shared_state().
*/ */
void void
_mesa_release_shared_state(struct gl_context *ctx, _mesa_reference_shared_state(struct gl_context *ctx,
struct gl_shared_state *shared) struct gl_shared_state **ptr,
struct gl_shared_state *state)
{ {
GLint RefCount; if (*ptr == state)
return;
_glthread_LOCK_MUTEX(shared->Mutex); if (*ptr) {
RefCount = --shared->RefCount; /* unref old state */
_glthread_UNLOCK_MUTEX(shared->Mutex); struct gl_shared_state *old = *ptr;
GLboolean delete;
assert(RefCount >= 0); _glthread_LOCK_MUTEX(old->Mutex);
assert(old->RefCount >= 1);
old->RefCount--;
delete = (old->RefCount == 0);
_glthread_UNLOCK_MUTEX(old->Mutex);
if (RefCount == 0) { if (delete) {
/* free shared state */ free_shared_state(ctx, old);
free_shared_state( ctx, shared ); }
*ptr = NULL;
}
if (state) {
/* reference new state */
_glthread_LOCK_MUTEX(state->Mutex);
state->RefCount++;
*ptr = state;
_glthread_UNLOCK_MUTEX(state->Mutex);
} }
} }

View file

@ -27,13 +27,14 @@
struct gl_context; struct gl_context;
void
_mesa_reference_shared_state(struct gl_context *ctx,
struct gl_shared_state **ptr,
struct gl_shared_state *state);
struct gl_shared_state * struct gl_shared_state *
_mesa_alloc_shared_state(struct gl_context *ctx); _mesa_alloc_shared_state(struct gl_context *ctx);
void
_mesa_release_shared_state(struct gl_context *ctx,
struct gl_shared_state *shared);
#endif #endif