From: Brian Paul Date: Wed, 1 Feb 2012 01:23:03 +0000 (-0700) Subject: mesa: use new _mesa_reference_shared_state() function X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=361cd53a77dd48fbf2a0321446c0b7c07365bff9;p=mesa.git 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 --- diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index f39cab5e4b6..43e7438ad4f 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -939,13 +939,10 @@ _mesa_initialize_context(struct gl_context *ctx, return GL_FALSE; } - _glthread_LOCK_MUTEX(shared->Mutex); - ctx->Shared = shared; - shared->RefCount++; - _glthread_UNLOCK_MUTEX(shared->Mutex); + _mesa_reference_shared_state(ctx, &ctx->Shared, shared); if (!init_attrib_groups( ctx )) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); return GL_FALSE; } @@ -973,7 +970,7 @@ _mesa_initialize_context(struct gl_context *ctx, } if (!ctx->Exec) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); return GL_FALSE; } #endif @@ -1002,7 +999,7 @@ _mesa_initialize_context(struct gl_context *ctx, #if FEATURE_dlist ctx->Save = _mesa_create_save_table(); if (!ctx->Save) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); free(ctx->Exec); return GL_FALSE; } @@ -1140,7 +1137,7 @@ _mesa_free_context_data( struct gl_context *ctx ) free(ctx->Save); /* 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 */ _mesa_free_display_list_data(ctx); @@ -1540,17 +1537,18 @@ GLboolean _mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { - struct gl_shared_state *oldSharedState = ctx->Shared; + struct gl_shared_state *oldShared = NULL; - ctx->Shared = ctxToShare->Shared; - - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - ctx->Shared->RefCount++; - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + /* save ref to old state to prevent it from being deleted immediately */ + _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared); + + /* update ctx's Shared pointer */ + _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared); 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; } diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index c3e93b5a583..c07ce823846 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -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 - * and all children structures. - * - * \param ctx GL context. - * \param shared shared state pointer. - * - * \sa free_shared_state(). + * gl_shared_state objects are ref counted. + * If ptr's refcount goes to zero, free the shared state. */ void -_mesa_release_shared_state(struct gl_context *ctx, - struct gl_shared_state *shared) +_mesa_reference_shared_state(struct gl_context *ctx, + struct gl_shared_state **ptr, + struct gl_shared_state *state) { - GLint RefCount; - - _glthread_LOCK_MUTEX(shared->Mutex); - RefCount = --shared->RefCount; - _glthread_UNLOCK_MUTEX(shared->Mutex); + if (*ptr == state) + return; + + if (*ptr) { + /* unref old state */ + struct gl_shared_state *old = *ptr; + GLboolean delete; + + _glthread_LOCK_MUTEX(old->Mutex); + assert(old->RefCount >= 1); + old->RefCount--; + delete = (old->RefCount == 0); + _glthread_UNLOCK_MUTEX(old->Mutex); + + if (delete) { + free_shared_state(ctx, old); + } - assert(RefCount >= 0); + *ptr = NULL; + } - if (RefCount == 0) { - /* free shared state */ - free_shared_state( ctx, shared ); + if (state) { + /* reference new state */ + _glthread_LOCK_MUTEX(state->Mutex); + state->RefCount++; + *ptr = state; + _glthread_UNLOCK_MUTEX(state->Mutex); } } diff --git a/src/mesa/main/shared.h b/src/mesa/main/shared.h index 55516a8c37c..3fe4578cf31 100644 --- a/src/mesa/main/shared.h +++ b/src/mesa/main/shared.h @@ -27,13 +27,14 @@ struct gl_context; -struct gl_shared_state * -_mesa_alloc_shared_state(struct gl_context *ctx); +void +_mesa_reference_shared_state(struct gl_context *ctx, + struct gl_shared_state **ptr, + struct gl_shared_state *state); -void -_mesa_release_shared_state(struct gl_context *ctx, - struct gl_shared_state *shared); +struct gl_shared_state * +_mesa_alloc_shared_state(struct gl_context *ctx); #endif