From df2ed4c7baf3ebf00337a75c637818f6958793f3 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Sun, 6 Nov 2011 10:47:46 +0200 Subject: [PATCH] glx: Test for WaitMSC crashing the server This is failed attemp to write test case for https://bugs.freedesktop.org/show_bug.cgi?id=36930 From the test case failing to crash server it is clear that I don't understand enough how IO buffer managment works in xserver. Signed-off-by: Pauli Nieminen --- CMakeLists.txt | 4 + tests/glx/CMakeLists.gl.txt | 1 + tests/glx/glx-wait-msc-close.c | 188 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 0 deletions(-) create mode 100644 tests/glx/glx-wait-msc-close.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2ca08..7682ee8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,10 @@ if(NOT import_numpy_error_code EQUAL 0) endif(NOT import_numpy_error_code EQUAL 0) if (NOT MSVC) + CHECK_C_COMPILER_FLAG("-std=gnu99" C_COMPILER_FLAG_STD99) + IF (C_COMPILER_FLAG_STD99) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") + ENDIF (C_COMPILER_FLAG_STD99) CHECK_C_COMPILER_FLAG("-Wall" C_COMPILER_FLAG_WALL) IF (C_COMPILER_FLAG_WALL) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") diff --git a/tests/glx/CMakeLists.gl.txt b/tests/glx/CMakeLists.gl.txt index 4560ef0..b569349 100644 --- a/tests/glx/CMakeLists.gl.txt +++ b/tests/glx/CMakeLists.gl.txt @@ -51,6 +51,7 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") add_executable (glx-visuals-stencil glx-visuals-stencil.c) add_executable (glx-copy-sub-buffer glx-copy-sub-buffer.c) + add_executable (glx-wait-msc-close glx-wait-msc-close.c) ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # vim: ft=cmake: diff --git a/tests/glx/glx-wait-msc-close.c b/tests/glx/glx-wait-msc-close.c new file mode 100644 index 0000000..c370b58 --- /dev/null +++ b/tests/glx/glx-wait-msc-close.c @@ -0,0 +1,188 @@ +/* + * Copyright © 2011 Pauli Nieminen + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Pauli Nieminen + */ + +/** + * @file glx-wait-msc-close.c + * + * Test glxWaitForMscOML being canceled when closing connection + */ + + +#include "glew.h" +#include "glxew.h" +#include "piglit-util.h" +#include "piglit-glx-util.h" + +#include +#include +#include + +int piglit_width = 40, piglit_height = 40; +static Window win; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static Display *dpy2; + +static pthread_t thread_close; +static pthread_t thread_wait; + +#define THREAD_WAIT_US 100000 + +static void * +thread_close_connection(void *arg) +{ + Display *dpy = arg; + pthread_mutex_lock(&mutex); + + /* Wait for main thread to send the request */ + usleep(THREAD_WAIT_US); + + /* Close connection to test if Xserver handles it correctly */ + XKillClient(dpy2, win); + XSync(dpy2, False); + + pthread_mutex_unlock(&mutex); + + return NULL; +} + +static void* +thread_wait_msc(void *arg) +{ + int32_t numerator; + int32_t denominator; + int64_t ust, msc, sbc, msc_wait; + Display *dpy = arg; + + pthread_mutex_lock(&mutex); + + if (!glXGetMscRateOML(dpy, win, &numerator, &denominator)) { + fprintf(stderr, "glXGetMscRateOML failed\n"); + return (void*)PIGLIT_FAIL; + } + + /* Calculate number of MSC increments in a second */ + msc_wait = numerator * 2; + msc_wait /= denominator; + msc_wait++; + msc_wait /= 2; + + /* scale to twice the thread wait time */ + msc_wait /= 1000*1000 / THREAD_WAIT_US / 2; + + pthread_create(&thread_close, NULL, thread_close_connection, dpy); + + if (!glXGetSyncValuesOML(dpy, win, &ust, &msc, &sbc)) { + fprintf(stderr, "glXGetSyncValuesOML failed\n"); + return (void *)PIGLIT_FAIL; + } + + msc_wait += msc; + + pthread_mutex_unlock(&mutex); + + if (!glXWaitForMscOML(dpy, win, msc_wait, 1, 0, &ust, &msc, &sbc)) + fprintf(stderr, "Canceled glXWaitForMscOML failed\n"); + + if (msc < msc_wait) + return (void *)PIGLIT_FAIL; + + return (void*)PIGLIT_PASS; +} + +enum piglit_result +wait(Display *dpy) +{ + enum piglit_result res; + void *r; + /* test that xserver is still up and running */ + pthread_create(&thread_wait, NULL, thread_wait_msc, dpy); + + pthread_join(thread_wait, &r); + res = (enum piglit_result)r; + if (res != PIGLIT_PASS) + return res; + + pthread_join(thread_close, NULL); + XSync(dpy2, False); + piglit_report_result(PIGLIT_PASS); +} + +int xio_error(Display *dpy) +{ + fprintf(stderr, "X io error handler called with dpy %d\n", + dpy != dpy2 ? 1 : 2); + if (dpy2 == dpy) + piglit_report_result(PIGLIT_FAIL); + else + pthread_exit(NULL); + return 0; +} + +int +main(int argc, char**argv) +{ + int i; + Display *dpy; + XVisualInfo *visinfo; + GLXContext ctx; + + for (i = 1; i < argc; i++) + if (!strcmp(argv[i], "-auto")) + piglit_automatic = 1; + + dpy = XOpenDisplay(NULL); + if (!dpy) { + fprintf(stderr, "Failed to open display\n"); + piglit_report_result(PIGLIT_FAIL); + } + + XSetIOErrorHandler(xio_error); + + piglit_require_glx_extension(dpy, "OML_sync_control"); + + dpy2 = XOpenDisplay(NULL); + if (!dpy2) { + fprintf(stderr, "Opening second X conenction failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + + visinfo = piglit_get_glx_visual(dpy); + win = piglit_get_glx_window(dpy, visinfo); + + XMapWindow(dpy, win); + + ctx = piglit_get_glx_context(dpy, visinfo); + glXMakeCurrent(dpy, win, ctx); + + if (glewInit()) { + fprintf(stderr, "glewInit failed\n"); + piglit_report_result(PIGLIT_FAIL); + } + piglit_glx_event_loop(dpy, wait); + + XFree(visinfo); + return 0; +} -- 1.7.7.1