--- st_cb_syncobj.c.orig 2016-10-14 10:52:02.867414704 +0900 +++ st_cb_syncobj.c 2016-10-15 09:44:30.238203506 +0900 @@ -80,17 +80,29 @@ { struct pipe_screen *screen = st_context(ctx)->pipe->screen; struct st_sync_object *so = (struct st_sync_object*)obj; + struct pipe_fence_handle * fence = NULL; + boolean success; + mtx_lock(&ctx->Shared->Mutex); + screen->fence_reference(screen, &fence, so->fence); + mtx_unlock(&ctx->Shared->Mutex); /* If the fence doesn't exist, assume it's signalled. */ - if (!so->fence) { + thrd_micro_random_sleep(); + if (!fence) { so->b.StatusFlag = GL_TRUE; - return; + goto quit; } - - if (screen->fence_finish(screen, so->fence, 0)) { + success = screen->fence_finish(screen, fence, 0); + thrd_micro_random_sleep(); + if (success) { + mtx_lock(&ctx->Shared->Mutex); screen->fence_reference(screen, &so->fence, NULL); + mtx_unlock(&ctx->Shared->Mutex); + thrd_micro_random_sleep(); so->b.StatusFlag = GL_TRUE; } + quit: + screen->fence_reference(screen, &fence, NULL); } static void st_client_wait_sync(struct gl_context *ctx, @@ -99,21 +111,32 @@ { struct pipe_screen *screen = st_context(ctx)->pipe->screen; struct st_sync_object *so = (struct st_sync_object*)obj; + struct pipe_fence_handle * fence = NULL; + boolean success; + mtx_lock(&ctx->Shared->Mutex); + screen->fence_reference(screen, &fence, so->fence); + mtx_unlock(&ctx->Shared->Mutex); /* If the fence doesn't exist, assume it's signalled. */ - if (!so->fence) { + thrd_micro_random_sleep(); + if (!fence) { so->b.StatusFlag = GL_TRUE; - return; + goto quit; } - + thrd_micro_random_sleep(); /* We don't care about GL_SYNC_FLUSH_COMMANDS_BIT, because flush is * already called when creating a fence. */ - - if (so->fence && - screen->fence_finish(screen, so->fence, timeout)) { + success = screen->fence_finish(screen, fence, timeout); + thrd_micro_random_sleep(); + if (success) { + mtx_lock(&ctx->Shared->Mutex); screen->fence_reference(screen, &so->fence, NULL); + mtx_unlock(&ctx->Shared->Mutex); + thrd_micro_random_sleep(); so->b.StatusFlag = GL_TRUE; } + quit: + screen->fence_reference(screen, &fence, NULL); } static void st_server_wait_sync(struct gl_context *ctx,