mesa: use new _mesa_reference_shared_state() function
authorBrian Paul <brianp@vmware.com>
Wed, 1 Feb 2012 01:23:03 +0000 (18:23 -0700)
committerBrian Paul <brianp@vmware.com>
Wed, 1 Feb 2012 14:11:40 +0000 (07:11 -0700)
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>
src/mesa/main/context.c
src/mesa/main/shared.c
src/mesa/main/shared.h

index f39cab5e4b66a088b37260b1abcd0fc07baeb321..43e7438ad4fe1157ac1d8d20e0e1cb3a1e1bf829 100644 (file)
@@ -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;
    }
index c3e93b5a583e9c8a73fc2b6244ceced9aecec5be..c07ce8238469a7ebe6c8ddaeffd3aaca32627422 100644 (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
- * 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);
    }
 }
index 55516a8c37c0c1a98e31231d8c2b32e71e3a0b34..3fe4578cf311e657d59e3104f3de6361d86a8b8f 100644 (file)
 
 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