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

Chris Wilson <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
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 <[email protected]>
Signed-off-by: Chris Wilson <[email protected]>
---

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

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.