From 6a22f9115b4fd301f9a8b92083d0f7cbeae094f0 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Sat, 11 Feb 2006 23:35:55 +0000 Subject: [PATCH] sys/: Fix up the XShm call testing so that we catch errors, and don't cause new ones by attempting to detach from a s... Original commit message from CVS: * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls): Fix up the XShm call testing so that we catch errors, and don't cause new ones by attempting to detach from a segment we failed to attach to. Fixes #312439. --- ChangeLog | 8 +++++++ sys/ximage/ximagesink.c | 47 ++++++++++++++++++++++++++------------- sys/xvimage/xvimagesink.c | 34 ++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index a145a85e5a..12ed7360d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-12 Jan Schmidt + + * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls): + * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls): + Fix up the XShm call testing so that we catch errors, and don't + cause new ones by attempting to detach from a segment we failed + to attach to. Fixes #312439. + 2006-02-10 Edward Hervey * gst/typefind/gsttypefindfunctions.c: (plugin_init): diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 3fa3be2940..e62d599a98 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -304,9 +304,17 @@ gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink, size_t size; int (*handler) (Display *, XErrorEvent *); gboolean result = FALSE; + gboolean did_attach = FALSE; g_return_val_if_fail (xcontext != NULL, FALSE); + /* Sync to ensure any older errors are already processed */ + XSync (xcontext->disp, FALSE); + + /* Set defaults so we don't free these later unnecessarily */ + SHMInfo.shmaddr = ((void *) -1); + SHMInfo.shmid = -1; + /* Setting an error handler to catch failure */ error_caught = FALSE; handler = XSetErrorHandler (gst_ximagesink_handle_xerror); @@ -316,7 +324,10 @@ gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink, ximage = XShmCreateImage (xcontext->disp, xcontext->visual, xcontext->depth, ZPixmap, NULL, &SHMInfo, 1, 1); - if (!ximage) { + + /* Might cause an error, sync to ensure it is noticed */ + XSync (xcontext->disp, FALSE); + if (!ximage || error_caught) { GST_WARNING ("could not XShmCreateImage a 1x1 image"); goto beach; } @@ -342,27 +353,31 @@ gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink, goto beach; } - XSync (xcontext->disp, 0); + /* Sync to ensure we see any errors we caused */ + XSync (xcontext->disp, FALSE); - /* Destroy the image */ - if (SHMInfo.shmaddr != ((void *) -1)) { - XShmDetach (xcontext->disp, &SHMInfo); - XSync (xcontext->disp, 0); - shmdt (SHMInfo.shmaddr); + if (!error_caught) { + did_attach = TRUE; + /* store whether we succeeded in result */ + result = TRUE; } + +beach: + /* Sync to ensure we swallow any errors we caused and reset error_caught */ + XSync (xcontext->disp, FALSE); + error_caught = FALSE; + XSetErrorHandler (handler); + + if (did_attach) { + XShmDetach (xcontext->disp, &SHMInfo); + XSync (xcontext->disp, FALSE); + } + if (SHMInfo.shmaddr != ((void *) -1)) + shmdt (SHMInfo.shmaddr); if (SHMInfo.shmid > 0) shmctl (SHMInfo.shmid, IPC_RMID, 0); if (ximage) XDestroyImage (ximage); - - /* store whether we succeeded in result and reset error_caught */ - result = !error_caught; - error_caught = FALSE; - -beach: - XSetErrorHandler (handler); - - XSync (xcontext->disp, FALSE); return result; } #endif /* HAVE_XSHM */ diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 009a6cf57b..babfeca1e3 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -382,9 +382,17 @@ gst_xvimagesink_check_xshm_calls (GstXContext * xcontext) gint size; int (*handler) (Display *, XErrorEvent *); gboolean result = FALSE; + gboolean did_attach = FALSE; g_return_val_if_fail (xcontext != NULL, FALSE); + /* Sync to ensure any older errors are already processed */ + XSync (xcontext->disp, FALSE); + + /* Set defaults so we don't free these later unnecessarily */ + SHMInfo.shmaddr = ((void *) -1); + SHMInfo.shmid = -1; + /* Setting an error handler to catch failure */ error_caught = FALSE; handler = XSetErrorHandler (gst_xvimagesink_handle_xerror); @@ -393,7 +401,10 @@ gst_xvimagesink_check_xshm_calls (GstXContext * xcontext) GST_DEBUG ("XvShmCreateImage of 1x1"); xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id, xcontext->im_format, NULL, 1, 1, &SHMInfo); - if (!xvimage) { + + /* Might cause an error, sync to ensure it is noticed */ + XSync (xcontext->disp, FALSE); + if (!xvimage || error_caught) { GST_WARNING ("could not XvShmCreateImage a 1x1 image"); goto beach; } @@ -419,19 +430,28 @@ gst_xvimagesink_check_xshm_calls (GstXContext * xcontext) goto beach; } - /* store whether we succeeded in result and reset error_caught */ - result = !error_caught; - error_caught = FALSE; + /* Sync to ensure we see any errors we caused */ + XSync (xcontext->disp, FALSE); + + if (!error_caught) { + did_attach = TRUE; + /* store whether we succeeded in result */ + result = TRUE; + } beach: + /* Sync to ensure we swallow any errors we caused and reset error_caught */ + XSync (xcontext->disp, FALSE); + + error_caught = FALSE; XSetErrorHandler (handler); - XSync (xcontext->disp, FALSE); - if (SHMInfo.shmaddr != ((void *) -1)) { + if (did_attach) { XShmDetach (xcontext->disp, &SHMInfo); XSync (xcontext->disp, FALSE); - shmdt (SHMInfo.shmaddr); } + if (SHMInfo.shmaddr != ((void *) -1)) + shmdt (SHMInfo.shmaddr); if (SHMInfo.shmid > 0) shmctl (SHMInfo.shmid, IPC_RMID, 0); if (xvimage)