diff options
author | Marek Olšák <[email protected]> | 2014-04-09 01:07:52 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-04-10 20:50:17 +0200 |
commit | 3b0b44f7def0acb4f7a7aef086c0bece321418a6 (patch) | |
tree | b156e7e948909c0a31d127d30099da60cb178b5d /src/gallium/winsys/radeon/drm | |
parent | ac330d4130cb005c75972da2a701b674413456ba (diff) |
winsys/radeon: fix a race condition in initialization of radeon_winsys::screen
Create the screen in the winsys while the mutex is locked.
This also results in a nice code cleanup!
Reviewed-by: Michel Dänzer <[email protected]>
Reviewed-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/winsys/radeon/drm')
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_public.h | 6 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 18 |
2 files changed, 21 insertions, 3 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_public.h b/src/gallium/winsys/radeon/drm/radeon_drm_public.h index 4fc62f1a400..dfcaaa4b6ef 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_public.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_public.h @@ -4,7 +4,11 @@ #include "pipe/p_defines.h" struct radeon_winsys; +struct pipe_screen; -struct radeon_winsys *radeon_drm_winsys_create(int fd); +typedef struct pipe_screen *(*radeon_screen_create_t)(struct radeon_winsys *); + +struct radeon_winsys * +radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create); #endif diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 07b3c05f2b7..0eb0c6a07b9 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -586,7 +586,8 @@ static bool radeon_winsys_unref(struct radeon_winsys *ws) return destroy; } -PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd) +PUBLIC struct radeon_winsys * +radeon_drm_winsys_create(int fd, radeon_screen_create_t screen_create) { struct radeon_drm_winsys *ws; @@ -609,7 +610,6 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd) } ws->fd = fd; - util_hash_table_set(fd_tab, intptr_to_pointer(fd), ws); if (!do_winsys_init(ws)) goto fail; @@ -652,6 +652,20 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd) if (ws->num_cpus > 1 && debug_get_option_thread()) ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws); + /* Create the screen at the end. The winsys must be initialized + * completely. + * + * Alternatively, we could create the screen based on "ws->gen" + * and link all drivers into one binary blob. */ + ws->base.screen = screen_create(&ws->base); + if (!ws->base.screen) { + radeon_winsys_destroy(&ws->base); + pipe_mutex_unlock(fd_tab_mutex); + return NULL; + } + + util_hash_table_set(fd_tab, intptr_to_pointer(fd), ws); + /* We must unlock the mutex once the winsys is fully initialized, so that * other threads attempting to create the winsys from the same fd will * get a fully initialized winsys and not just half-way initialized. */ |