[cairo] [PATCH] xlib/shm: Sync the XShmAttach before removing the ShmSegment id

Chris Wilson chris at chris-wilson.co.uk
Fri Oct 19 04:11:59 PDT 2012


Whilst reading through other users of XShm, it became apparent that
IPC_RMID behaves differently across the platforms. Linux allows
processes to attach to an existing ShmSegment id after a IPC_RMID, but
for others the IPC_RMID takes immediate effect. On those platforms
without a "deferred" IPC_RMID, we then need to perform the XShmAttach
synchronously before perfomring the IPC_RMID.

Reported-by: Thomas Klausner <wiz at NetBSD.org>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---

Thomas, can you please test the configure magic on your NetBSD box?
Thanks,
-Chris

---
 configure.ac                 |   32 ++++++++++++++++++++++++++++++++
 src/cairo-xlib-surface-shm.c |    3 +++
 2 files changed, 35 insertions(+)

diff --git a/configure.ac b/configure.ac
index 67b68e2..017e81a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,6 +74,38 @@ CAIRO_ENABLE_SURFACE_BACKEND(xlib, Xlib, auto, [
 		       xlib_NONPKGCONFIG_LIBS="$X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS"
 		       xlib_NONPKGCONFIG_CFLAGS=$X_CFLAGS
 		     fi])
+
+  AC_CHECK_HEADER(sys/ipc.h)
+  AC_CHECK_HEADER(sys/shm.h)
+
+  if test "$ac_cv_header_sys_ipc_h" = "yes" -a "$ac_cv_header_sys_shm_h" = "yes"; then
+      AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
+      AC_TRY_RUN([
+		  #include <sys/types.h>
+		  #include <sys/ipc.h>
+		  #include <sys/shm.h>
+		  int main()
+		  {
+		      char *shmaddr;
+		      int id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600);
+		      if (id == -1) return 2;
+		      shmaddr = shmat (id, 0, 0);
+		      shmctl (id, IPC_RMID, 0);
+		      if ((char*) shmat (id, 0, 0) == (char*) -1) {
+			  shmdt (shmaddr);
+			  return 1;
+		      }
+		      shmdt (shmaddr);
+		      shmdt (shmaddr);
+		      return 0;
+		  }
+		  ],
+		  AC_DEFINE(IPC_RMID_DEFERRED_RELEASE, 1,
+			    [Define to 1 if shared memory segments are released deferred.])
+		  AC_MSG_RESULT(yes),
+		  AC_MSG_RESULT(no),
+		  AC_MSG_RESULT(assuming no))
+      fi
 ])
 
 CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index ec8a6e1..ec0d334 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -449,6 +449,9 @@ _cairo_xlib_shm_pool_create(cairo_xlib_display_t *display,
 
     pool->attached = NextRequest (dpy);
     success = XShmAttach (dpy, &pool->shm);
+#if !IPC_RMID_DEFERRED_RELEASE
+    XSync (dpy, FALSE);
+#endif
     shmctl (pool->shm.shmid, IPC_RMID, NULL);
 
     if (! success)
-- 
1.7.10.4



More information about the cairo mailing list