Author: spitzak
Date: 2007-07-24 04:25:53 -0700 (Tue, 24 Jul 2007)
New Revision: 5936
Log:
After a few months of crashes after running stuff many times here, it
was pointed out to me that XShm permanently leaks memory (actually it
looks like the real culprit is sysv ipc) and thus is pretty useless if
there is the slightest chance your program will crash. So it is now
disabled by default. It may be better to use if for "large" images and
add an automatic destructor, though you still lose if the program crashes,
and there are also indications that Xv would be a better api.
Modified:
trunk/OpenGL/Fl_Gl_Choice.cxx
trunk/OpenGL/Fl_Gl_Window.cxx
trunk/configh.in
trunk/configure.in
trunk/src/x11/Image.cxx
Modified: trunk/OpenGL/Fl_Gl_Choice.cxx
===================================================================
--- trunk/OpenGL/Fl_Gl_Choice.cxx 2007-07-23 21:14:48 UTC (rev 5935)
+++ trunk/OpenGL/Fl_Gl_Choice.cxx 2007-07-24 11:25:53 UTC (rev 5936)
@@ -302,6 +302,14 @@
aglSetDrawable(context, GetWindowPort( xid(window) ) );
aglSetCurrentContext(context);
#endif
+# if USE_GLEW
+ static bool beenhere = false;
+ if (!beenhere) {
+ beenhere = true;
+ glewExperimental = GL_TRUE;
+ glewInit();
+ }
+# endif
}
}
Modified: trunk/OpenGL/Fl_Gl_Window.cxx
===================================================================
--- trunk/OpenGL/Fl_Gl_Window.cxx 2007-07-23 21:14:48 UTC (rev 5935)
+++ trunk/OpenGL/Fl_Gl_Window.cxx 2007-07-24 11:25:53 UTC (rev 5936)
@@ -254,10 +254,6 @@
mode_ &= ~NON_LOCAL_CONTEXT;
context_ = create_gl_context(this, gl_choice);
set_gl_context(this, context_);
-#if USE_GLEW
- glewExperimental = GL_TRUE;
- glewInit();
-#endif
valid(0);
} else {
set_gl_context(this, context_);
Modified: trunk/configh.in
===================================================================
--- trunk/configh.in 2007-07-23 21:14:48 UTC (rev 5935)
+++ trunk/configh.in 2007-07-24 11:25:53 UTC (rev 5936)
@@ -77,9 +77,11 @@
#define USE_CLIPOUT 0
/* Use the MIT_SHM extension to share memory between the program
- and X server for images, if possible.
+ and X server for images, if possible. This is disabled by default
+ as it will permanently leak system memory if your program crashes
+ or otherwise exits without destroying the Image objects.
*/
-#define USE_XSHM 1
+#define USE_XSHM 0
/* Do we have the X double-buffer extension header file
<X11/extensions/Xdbe.h>? Turning this on will make the list_visuals
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2007-07-23 21:14:48 UTC (rev 5935)
+++ trunk/configure.in 2007-07-24 11:25:53 UTC (rev 5936)
@@ -684,8 +684,8 @@
fi
dnl Check for the Xshm extension unless disabled...
- AC_ARG_ENABLE(xshm, [ --enable-xshm turn on MIT-SHM support
(default=yes)])
- if test x$enable_xshm != xno; then
+ AC_ARG_ENABLE(xshm, [ --enable-xshm turn on MIT-SHM support
(default=no)])
+ if test x$enable_xshm == xyes; then
AC_CHECK_HEADER(X11/extensions/XShm.h, AC_DEFINE(USE_XSHM),,
[#include <X11/Xlib.h>])
fi
Modified: trunk/src/x11/Image.cxx
===================================================================
--- trunk/src/x11/Image.cxx 2007-07-23 21:14:48 UTC (rev 5935)
+++ trunk/src/x11/Image.cxx 2007-07-24 11:25:53 UTC (rev 5936)
@@ -30,6 +30,13 @@
// Anything with a 8 bits_per_pixel bitmaps (visual depth may be less)
// 16-bit TrueColor with arbitrary layout
// 32-bit TrueColor with ARGB32 layout
+//
+// Code for using X Shared Memory is here but is normally disabled by
+// configure. This is because the current implementation will leak the
+// memory permanently (as ipshm segments) if the images are not destroyed
+// (which they won't be if your program crashes, no matter how many
+// automatic destructors you create. Therefore this is Windows3.1-style
+// stupidity).
#include <fltk/error.h>
#include <fltk/math.h>
@@ -1029,41 +1036,42 @@
syncro = 0;
if (use_xshm_pixmaps) {
shminfo.shmid = shmget(IPC_PRIVATE, n, IPC_CREAT|0777);
- if (shminfo.shmid != -1)
+ if (shminfo.shmid != -1) {
shminfo.shmaddr = (char*)shmat(shminfo.shmid, 0, 0);
- else
- shminfo.shmaddr = 0;
- } else {
- shminfo.shmid = -1;
- shminfo.shmaddr = 0;
- }
- shminfo.readOnly = False;
- if (shminfo.shmaddr && XShmAttach(xdisplay, &shminfo)) {
- data = (uchar*)shminfo.shmaddr;
- static bool beenhere;
- if (beenhere) {
- rgb = XShmCreatePixmap(xdisplay, RootWindow(xdisplay,xscreen),
- shminfo.shmaddr, &shminfo,
- w, h, depth);
- return;
+ if (shminfo.shmaddr) {
+ shminfo.readOnly = False;
+ if (XShmAttach(xdisplay, &shminfo)) {
+ data = (uchar*)shminfo.shmaddr;
+ static bool beenhere;
+ if (beenhere) {
+ rgb = XShmCreatePixmap(xdisplay, RootWindow(xdisplay,xscreen),
+ shminfo.shmaddr, &shminfo,
+ w, h, depth);
+ return;
+ }
+ beenhere = true;
+ // The first time, we will do an XSync and detect if it throws
+ // an error. This seems to be the only way to see if XShm is
+ // going to work, it won't work on remote displays but amazingly
+ // enough no api is provided to tell you that!
+ int (*f)(Display*,XErrorEvent*) = XSetErrorHandler(xerror_handler);
+ rgb = XShmCreatePixmap(xdisplay, RootWindow(xdisplay,xscreen),
+ shminfo.shmaddr, &shminfo,
+ w, h, depth);
+ XSync(xdisplay,false);
+ XSetErrorHandler(f);
+ if (use_xshm_pixmaps) return; // the xerror_handler did not get
called!
+ // Okay, clean up all the failed stuff we created,
+ // and continue with non-Xshm code:
+ XShmDetach(xdisplay, &shminfo);
+ }
+ shmdt(shminfo.shmaddr);
+ }
+ shmctl(shminfo.shmid, IPC_RMID, 0);
}
- beenhere = true;
- // The first time, we will do an XSync and detect if it throws
- // an error. This seems to be the only way to see if XShm is
- // going to work, it won't work on remote displays but amazingly
- // enough no api is provided to tell you that!
- int (*f)(Display*,XErrorEvent*) = XSetErrorHandler(xerror_handler);
- rgb = XShmCreatePixmap(xdisplay, RootWindow(xdisplay,xscreen),
- shminfo.shmaddr, &shminfo,
- w, h, depth);
- XSync(xdisplay,false);
- XSetErrorHandler(f);
- if (use_xshm_pixmaps) return; // the xerror_handler did not get called!
- //printf("XShm is not going to work!\n");
- // throw stuff away and continue with non-Xshm code:
- shmdt(shminfo.shmaddr); data = 0; shminfo.shmaddr = 0;
- shmctl(shminfo.shmid, IPC_RMID, 0); shminfo.shmid = -1;
}
+ shminfo.shmid = -1;
+ shminfo.shmaddr = 0;
#endif
rgb = XCreatePixmap(xdisplay, RootWindow(xdisplay,xscreen),
w, h, depth);
@@ -1103,8 +1111,11 @@
if (rgb) XFreePixmap(xdisplay, rgb);
}
#if USE_XSHM
- if (shminfo.shmaddr) {shmdt(shminfo.shmaddr); data = 0;}
- if (shminfo.shmid != -1) shmctl(shminfo.shmid, IPC_RMID, 0);
+ if (shminfo.shmaddr) {
+ if (xdisplay) XShmDetach(xdisplay, &shminfo);
+ shmdt(shminfo.shmaddr); data = 0;
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+ }
#endif
delete[] (U32*)data;
}
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit