? xshm-check.patch
Index: ximage/ximagesink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/sys/ximage/ximagesink.c,v
retrieving revision 1.152
diff -u -r1.152 ximagesink.c
--- ximage/ximagesink.c	26 Jan 2006 19:17:38 -0000	1.152
+++ ximage/ximagesink.c	11 Feb 2006 23:25:19 -0000
@@ -304,9 +304,17 @@
   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 @@
 
   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 @@
     goto beach;
   }
 
-  XSync (xcontext->disp, 0);
+  /* 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;
+  }
 
-  /* Destroy the image */
-  if (SHMInfo.shmaddr != ((void *) -1)) {
+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, 0);
-    shmdt (SHMInfo.shmaddr);
+    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 */
Index: xvimage/xvimagesink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/sys/xvimage/xvimagesink.c,v
retrieving revision 1.143
diff -u -r1.143 xvimagesink.c
--- xvimage/xvimagesink.c	27 Jan 2006 01:36:01 -0000	1.143
+++ xvimage/xvimagesink.c	11 Feb 2006 23:25:21 -0000
@@ -382,9 +382,17 @@
   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_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 @@
     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);
+  }  
+  if (SHMInfo.shmaddr != ((void *) -1)) 
     shmdt (SHMInfo.shmaddr);
-  }
   if (SHMInfo.shmid > 0)
     shmctl (SHMInfo.shmid, IPC_RMID, 0);
   if (xvimage)

