Looks solid to me Brian. Jose
----- Original Message ----- > 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. > --- > src/mesa/main/context.c | 28 ++++++++++++-------------- > src/mesa/main/shared.c | 48 > +++++++++++++++++++++++++++++----------------- > src/mesa/main/shared.h | 11 +++++---- > 3 files changed, 49 insertions(+), 38 deletions(-) > > diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c > index f39cab5..43e7438 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 c3e93b5..c07ce82 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 55516a8..3fe4578 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 > -- > 1.7.3.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev