--- st_cb_syncobj.c.orig 2016-10-14 10:52:02.867414704 +0900 +++ st_cb_syncobj.c 2016-10-18 01:31:48.477581393 +0900 @@ -36,21 +36,25 @@ #include "pipe/p_screen.h" #include "st_context.h" #include "st_cb_syncobj.h" +#include struct st_sync_object { struct gl_sync_object b; - struct pipe_fence_handle *fence; + mtx_t mtx; }; static struct gl_sync_object * st_new_sync_object(struct gl_context *ctx, GLenum type) { - if (type == GL_SYNC_FENCE) - return (struct gl_sync_object*)CALLOC_STRUCT(st_sync_object); - else - return NULL; + if (type == GL_SYNC_FENCE) { + struct st_sync_object * so = + (struct st_sync_object*)CALLOC_STRUCT(st_sync_object); + mtx_init(&so->mtx, mtx_plain); + return (struct gl_sync_object *)so; + } + return NULL; } static void st_delete_sync_object(struct gl_context *ctx, @@ -61,6 +65,7 @@ screen->fence_reference(screen, &so->fence, NULL); free(so->b.Label); + mtx_destroy(&so->mtx); free(so); } @@ -82,15 +87,12 @@ struct st_sync_object *so = (struct st_sync_object*)obj; /* If the fence doesn't exist, assume it's signalled. */ - if (!so->fence) { - so->b.StatusFlag = GL_TRUE; - return; - } - - if (screen->fence_finish(screen, so->fence, 0)) { + mtx_lock(&so->mtx); + if (so->fence && screen->fence_finish(screen, so->fence, 0)) { screen->fence_reference(screen, &so->fence, NULL); so->b.StatusFlag = GL_TRUE; } + mtx_unlock(&so->mtx); } static void st_client_wait_sync(struct gl_context *ctx, @@ -100,20 +102,15 @@ struct pipe_screen *screen = st_context(ctx)->pipe->screen; struct st_sync_object *so = (struct st_sync_object*)obj; - /* If the fence doesn't exist, assume it's signalled. */ - if (!so->fence) { - so->b.StatusFlag = GL_TRUE; - return; - } - /* 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)) { + mtx_lock(&so->mtx); + /* If the fence doesn't exist, assume it's signalled. */ + if (so->fence && screen->fence_finish(screen, so->fence, timeout)) { screen->fence_reference(screen, &so->fence, NULL); so->b.StatusFlag = GL_TRUE; } + mtx_unlock(&so->mtx); } static void st_server_wait_sync(struct gl_context *ctx,