forked from pool/xorg-x11-server
This commit is contained in:
parent
4f4e76f308
commit
be7f6c979e
139
bug-211314_p_drawable_privclean.diff
Normal file
139
bug-211314_p_drawable_privclean.diff
Normal file
@ -0,0 +1,139 @@
|
||||
Novell Bugzilla #211314 and others
|
||||
Maybe Xorg Bugzilla #7205 and probably others
|
||||
|
||||
|
||||
Programs apparently crash if a context is reused for a window that changed in
|
||||
the meantime. Crashes apparently only occure for software rendering.
|
||||
|
||||
The basic problem is that a buffer is freed, when the according window is
|
||||
closed, but the old context (which is no longer referenced in _glapi_Context
|
||||
or in the according glxPriv structures) still has a reference to this buffer,
|
||||
and is reactivated later. As the buffer points to a freed memory location, it
|
||||
is no longer recognized as an old buffer (because buffer->Name - by accident -
|
||||
contains 0x00cccccc) and not replaced.
|
||||
|
||||
|
||||
About this patch:
|
||||
|
||||
The correct way to remove the reference would be to nuke it when a context is
|
||||
disassociated from a drawable - because after that only the Xserver itself
|
||||
(and not the Mesa subsystem) knows about the context which still has the stray
|
||||
buffer and glxPriv pointers.
|
||||
Unfortunately, if you do that, the server crashes in glxSwapBuffers() - I
|
||||
don't known enough about that code to decide, whether this is a broken
|
||||
implementation, a bug in glxSwapBuffers() (there might be other calls), broken
|
||||
by design, or deliberately chosen this way and actually correct.
|
||||
|
||||
So the only way is to scan all contexts known for this client for references
|
||||
to this buffer (and the according private structure) when the buffer is
|
||||
actually destroyed. This is done in __glXMesaDrawableDestroy(), which has
|
||||
access to all needed data - all but one.
|
||||
|
||||
Scanning all contexts only needs the client id (which is known), but the API
|
||||
call FindClientResourcesByType() actually needs a ClientPtr - just to extract
|
||||
the client id! The ClientPtr is only known in glxext.c in a static array
|
||||
__glXClients. I don't know of a different API to get the ClientPtr from, so I
|
||||
exported it. One other possibility would be to add a ClientPtr fetch call to
|
||||
glxext.c, another one to create a new FindClientIDResourcesByType(), another
|
||||
one to create a Client structure with just the id included (ugh!) just for
|
||||
this API call. Making the array extern was the simplest thing to do, but is
|
||||
not necessarily the right solution.
|
||||
|
||||
There is probably has a better / right possibility to remove all pointers to
|
||||
the buffer (MakeCurrent2?) - but I don't have a better idea ATM.
|
||||
|
||||
As I consider this a workaround / saveguard for some deeply involved buffer
|
||||
handling bug, I added a lot of ErrorF()s that indicate these failures. If
|
||||
removing these references at this point is the only valid solution, I'd gladly
|
||||
remove these. As the scanning is only invoked on buffer destroys and doesn't
|
||||
do a lot of scanning, performance is not an issue here.
|
||||
|
||||
Matthias Hopf <mhopf@suse.de>
|
||||
|
||||
|
||||
--- GL/glx/glxext.c.orig 2007-01-23 16:00:19.000000000 +0100
|
||||
+++ GL/glx/glxext.c 2007-01-23 16:00:23.000000000 +0100
|
||||
@@ -59,7 +59,7 @@ xGLXSingleReply __glXReply;
|
||||
** A set of state for each client. The 0th one is unused because client
|
||||
** indices start at 1, not 0.
|
||||
*/
|
||||
-static __GLXclientState *__glXClients[MAXCLIENTS + 1];
|
||||
+__GLXclientState *__glXClients[MAXCLIENTS + 1];
|
||||
|
||||
/*
|
||||
** Forward declarations.
|
||||
|
||||
--- GL/mesa/X/xf86glx.c.orig 2007-01-23 12:48:28.000000000 +0100
|
||||
+++ GL/mesa/X/xf86glx.c 2007-01-23 19:37:23.000000000 +0100
|
||||
@@ -95,12 +95,70 @@ static XMesaVisual find_mesa_visual(__GL
|
||||
|
||||
|
||||
static void
|
||||
+__glXMesaDrawableDestoryCB(pointer baseCtx, XID id, pointer basePriv)
|
||||
+{
|
||||
+ __GLXMESAcontext *context = (__GLXMESAcontext *) baseCtx;
|
||||
+ __GLXdrawable *glxPriv = (__GLXdrawable *) basePriv;
|
||||
+ void *buffer =((__GLXMESAdrawable *) glxPriv) ->xm_buf;
|
||||
+ __GLXMESAdrawable *drawPriv, *readPriv;
|
||||
+
|
||||
+ if (context->base.drawPriv == glxPriv ||
|
||||
+ context->base.readPriv == glxPriv) {
|
||||
+ ErrorF ("Cleaning up stray priv pointers to %p in context %p\n",
|
||||
+ glxPriv, context);
|
||||
+ if (context->base.drawPriv == glxPriv)
|
||||
+ context->base.drawPriv = NULL;
|
||||
+ if (context->base.readPriv == glxPriv)
|
||||
+ context->base.readPriv = NULL;
|
||||
+ }
|
||||
+ drawPriv = (__GLXMESAdrawable *) context->base.drawPriv;
|
||||
+ readPriv = (__GLXMESAdrawable *) context->base.readPriv;
|
||||
+ if ((drawPriv && drawPriv->xm_buf == buffer) ||
|
||||
+ (readPriv && readPriv->xm_buf == buffer)) {
|
||||
+ /* This should not happen, but the alternative is a sure server crash */
|
||||
+ ErrorF ("ERROR: Draw priv in context %p is not freed yet, "
|
||||
+ "but has stray buffer pointer %p\n", context, buffer);
|
||||
+ if (drawPriv && drawPriv->xm_buf == buffer)
|
||||
+ drawPriv->xm_buf = NULL;
|
||||
+ if (readPriv && readPriv->xm_buf == buffer)
|
||||
+ readPriv->xm_buf = NULL;
|
||||
+ }
|
||||
+ if (context->xmesa &&
|
||||
+ (context->xmesa->mesa.DrawBuffer == buffer ||
|
||||
+ context->xmesa->mesa.ReadBuffer == buffer ||
|
||||
+ context->xmesa->mesa.WinSysDrawBuffer == buffer ||
|
||||
+ context->xmesa->mesa.WinSysReadBuffer == buffer ||
|
||||
+ context->xmesa->xm_buffer == buffer)) {
|
||||
+ ErrorF ("Cleaning up stray xmesa pointers to buffer %p in context %p\n",
|
||||
+ buffer, context);
|
||||
+ if (context->xmesa->mesa.DrawBuffer == buffer)
|
||||
+ context->xmesa->mesa.DrawBuffer = NULL;
|
||||
+ if (context->xmesa->mesa.ReadBuffer == buffer)
|
||||
+ context->xmesa->mesa.ReadBuffer = NULL;
|
||||
+ if (context->xmesa->mesa.WinSysDrawBuffer == buffer)
|
||||
+ context->xmesa->mesa.WinSysDrawBuffer = NULL;
|
||||
+ if (context->xmesa->mesa.WinSysReadBuffer == buffer)
|
||||
+ context->xmesa->mesa.WinSysReadBuffer = NULL;
|
||||
+ if (context->xmesa->xm_buffer == buffer)
|
||||
+ context->xmesa->xm_buffer = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+extern __GLXclientState *__glXClients[];
|
||||
+static void
|
||||
__glXMesaDrawableDestroy(__GLXdrawable *base)
|
||||
{
|
||||
__GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
|
||||
+ ClientPtr client = __glXClients[CLIENT_ID(base->drawId)]->client;
|
||||
|
||||
- if (glxPriv->xm_buf != NULL)
|
||||
+ if (glxPriv->xm_buf != NULL) {
|
||||
+ /* There may still be stray pointers in contexts that are no longer
|
||||
+ * visible to Mesa. Scan all contexts for this client and nuke those
|
||||
+ * pointers */
|
||||
+ FindClientResourcesByType(client, __glXContextRes,
|
||||
+ __glXMesaDrawableDestoryCB, glxPriv);
|
||||
XMesaDestroyBuffer(glxPriv->xm_buf);
|
||||
+ }
|
||||
xfree(glxPriv);
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 24 18:01:06 CET 2007 - sndirsch@suse.de
|
||||
|
||||
- bug-211314_p_drawable_privclean.diff:
|
||||
* fixes Xserver crash in Mesa software rendering path (Bug #211314)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jan 23 11:45:28 CET 2007 - sndirsch@suse.de
|
||||
|
||||
|
@ -21,7 +21,7 @@ BuildRequires: libjpeg-devel
|
||||
URL: http://xorg.freedesktop.org/
|
||||
%define EXPERIMENTAL 0
|
||||
Version: 7.2
|
||||
Release: 45
|
||||
Release: 46
|
||||
License: X11/MIT
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
Group: System/X11/Servers/XF86_4
|
||||
@ -80,6 +80,7 @@ Patch40: 0018-vnc-support.txt.diff
|
||||
Patch41: loadmod-bug197195.diff
|
||||
Patch42: bug227111-ddc_screensize.diff
|
||||
Patch43: bug-211314_mesa-context.diff
|
||||
Patch44: bug-211314_p_drawable_privclean.diff
|
||||
Patch334: p_pci-domain.diff
|
||||
Patch357: p_pci-ce-x.diff
|
||||
|
||||
@ -172,6 +173,7 @@ popd
|
||||
%patch42 -p1
|
||||
pushd ../Mesa
|
||||
%patch43 -p0
|
||||
%patch44 -p0
|
||||
popd
|
||||
|
||||
%build
|
||||
@ -496,6 +498,9 @@ exit 0
|
||||
%endif
|
||||
|
||||
%changelog -n xorg-x11-server
|
||||
* Wed Jan 24 2007 - sndirsch@suse.de
|
||||
- bug-211314_p_drawable_privclean.diff:
|
||||
* fixes Xserver crash in Mesa software rendering path (Bug #211314)
|
||||
* Tue Jan 23 2007 - sndirsch@suse.de
|
||||
- xserver 1.2.0 release
|
||||
* Bug #9219: Return BadMatch when trying to name the backing
|
||||
|
Loading…
Reference in New Issue
Block a user