summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-08-23 16:57:50 +0200
committerAlexander Larsson <alexl@redhat.com>2010-08-24 10:23:26 +0200
commit7c61dfee893da1ea1ee48aa8590ffb52afa573b8 (patch)
treef3e23394e69d41f0adeeaa980a03633b6c4e747a
parenta960598e23309712622782ba7e65e0c957e9b2d9 (diff)
Don't try xshm any more if it fails for a permanent reason
This is copied from how Gtk+ detects Xshm failures.
-rw-r--r--client/x11/platform.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp
index 3b9f4af..1b54bc3 100644
--- a/client/x11/platform.cpp
+++ b/client/x11/platform.cpp
@@ -242,22 +242,38 @@ XImage *XPlatform::create_x_shm_image(RedDrawable::Format format,
format == RedDrawable::A1 ? XYBitmap : ZPixmap,
NULL, shminfo, width, height);
if (image == NULL) {
+ x_shm_avail = false;
goto err1;
}
shminfo->shmid = shmget(IPC_PRIVATE, height * image->bytes_per_line,
IPC_CREAT | 0777);
if (shminfo->shmid < 0) {
+ /* EINVAL indicates, most likely, that the segment we asked for
+ * is bigger than SHMMAX, so we don't treat it as a permanent
+ * error. ENOSPC and ENOMEM may also indicate this, but
+ * more likely are permanent errors.
+ */
+ if (errno != EINVAL) {
+ x_shm_avail = false;
+ }
goto err2;
}
shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0);
if (!shminfo->shmaddr) {
+ /* Failure in shmat is almost certainly permanent. Most likely error is
+ * EMFILE, which would mean that we've exceeded the per-process
+ * Shm segment limit.
+ */
+ x_shm_avail = false;
+
goto err2;
}
shminfo->readOnly = False;
if (!XShmAttach(XPlatform::get_display(), shminfo)) {
+ x_shm_avail = false;
goto err2;
}