From 063f752e0de1362f47a81da299ffee9e283c8026 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 13 Oct 2016 04:54:43 -0700 Subject: [PATCH] Fixed bug 3328 - Race condition in Wayland_VideoInit Robert Folland When running this little test program with SDL2 on Wayland it often crashes in SDL_Init. From a backtrace it is apparent that there is a race condition in creating a xkb_context_ref. Sometimes it is 0x0. By moving the relevant lines higher up in Wayland_VideoInit (in SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302) this seems to get fixed. I moved the call to WAYLAND_xkb_context_new() up to before the call to WAYLAND_wl_display_connect(). Here is the test program (just a loop of init and quit), and a backtrace from gdb: #include #include #include #include #include int main(int argc, char **argv) { int count = atoi(argv[1]); for (int i = 0; i < count; i++) { std::cout << "Init " << i << std::endl; if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 1; } std::cout << "Quit" << std::endl; SDL_Quit(); } return 0; } Init 12 Quit Init 13 Program received signal SIGSEGV, Segmentation fault. xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156 156 ctx->refcnt++; (gdb) bt #0 xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156 #1 0x00007ffff5e1cd4c in xkb_keymap_new (ctx=0x0, format=XKB_KEYMAP_FORMAT_TEXT_V1, flags=flags@entry=XKB_KEYMAP_COMPILE_NO_FLAGS) at src/keymap-priv.c:65 #2 0x00007ffff5e1c6cc in xkb_keymap_new_from_buffer (ctx=, buffer=0x7ffff7fd5000 "xkb_keymap {\nxkb_keycodes \"(unnamed)\" {\n\tminimum = 8;\n\tmaximum = 255;\n\t", ' ' , "= 9;\n\t", ' ' , "= 10;\n\t", ' ' , "= 11;\n\t", ' ' , "= 12;\n\t", ' ' ..., length=48090, format=, flags=) at src/keymap.c:191 #3 0x00007ffff7b8ea4e in keyboard_handle_keymap (data=0x6169b0, keyboard=, format=, fd=5, size=48091) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandevents.c:269 #4 0x00007ffff64501f0 in ffi_call_unix64 () from /usr/lib/libffi.so.6 #5 0x00007ffff644fc58 in ffi_call () from /usr/lib/libffi.so.6 #6 0x00007ffff665be3e in wl_closure_invoke (closure=closure@entry=0x61f000, flags=flags@entry=1, target=, target@entry=0x616d20, opcode=opcode@entry=0, data=) at src/connection.c:949 #7 0x00007ffff6658be0 in dispatch_event (display=, queue=) at src/wayland-client.c:1274 #8 0x00007ffff6659db4 in dispatch_queue (queue=0x617398, display=0x6172d0) at src/wayland-client.c:1420 #9 wl_display_dispatch_queue_pending (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1662 #10 0x00007ffff665a0cf in wl_display_roundtrip_queue (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1085 #11 0x00007ffff7b8faa0 in Wayland_VideoInit (_this=) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302 #12 0x00007ffff7b7aed6 in SDL_VideoInit_REAL (driver_name=, driver_name@entry=0x0) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/SDL_video.c:513 #13 0x00007ffff7ae0ee7 in SDL_InitSubSystem_REAL (flags=16416) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/SDL.c:173 #14 0x0000000000400b24 in main (argc=2, argv=0x7fffffffebb8) at vplay-init.cpp:13 (gdb) --- src/video/wayland/SDL_waylandvideo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 0660ae23a3e87..554b0ecada164 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -340,6 +340,11 @@ Wayland_VideoInit(_THIS) _this->driverdata = data; + data->xkb_context = WAYLAND_xkb_context_new(0); + if (!data->xkb_context) { + return SDL_SetError("Failed to create XKB context"); + } + data->display = WAYLAND_wl_display_connect(NULL); if (data->display == NULL) { return SDL_SetError("Failed to connect to a Wayland display"); @@ -358,11 +363,6 @@ Wayland_VideoInit(_THIS) // Second roundtrip to receive all output events. WAYLAND_wl_display_roundtrip(data->display); - data->xkb_context = WAYLAND_xkb_context_new(0); - if (!data->xkb_context) { - return SDL_SetError("Failed to create XKB context"); - } - Wayland_InitMouse(); /* Get the surface class name, usually the name of the application */