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
|
Tue Jan 23 11:45:28 CET 2007 - sndirsch@suse.de
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ BuildRequires: libjpeg-devel
|
|||||||
URL: http://xorg.freedesktop.org/
|
URL: http://xorg.freedesktop.org/
|
||||||
%define EXPERIMENTAL 0
|
%define EXPERIMENTAL 0
|
||||||
Version: 7.2
|
Version: 7.2
|
||||||
Release: 45
|
Release: 46
|
||||||
License: X11/MIT
|
License: X11/MIT
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
Group: System/X11/Servers/XF86_4
|
Group: System/X11/Servers/XF86_4
|
||||||
@ -80,6 +80,7 @@ Patch40: 0018-vnc-support.txt.diff
|
|||||||
Patch41: loadmod-bug197195.diff
|
Patch41: loadmod-bug197195.diff
|
||||||
Patch42: bug227111-ddc_screensize.diff
|
Patch42: bug227111-ddc_screensize.diff
|
||||||
Patch43: bug-211314_mesa-context.diff
|
Patch43: bug-211314_mesa-context.diff
|
||||||
|
Patch44: bug-211314_p_drawable_privclean.diff
|
||||||
Patch334: p_pci-domain.diff
|
Patch334: p_pci-domain.diff
|
||||||
Patch357: p_pci-ce-x.diff
|
Patch357: p_pci-ce-x.diff
|
||||||
|
|
||||||
@ -172,6 +173,7 @@ popd
|
|||||||
%patch42 -p1
|
%patch42 -p1
|
||||||
pushd ../Mesa
|
pushd ../Mesa
|
||||||
%patch43 -p0
|
%patch43 -p0
|
||||||
|
%patch44 -p0
|
||||||
popd
|
popd
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -496,6 +498,9 @@ exit 0
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog -n xorg-x11-server
|
%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
|
* Tue Jan 23 2007 - sndirsch@suse.de
|
||||||
- xserver 1.2.0 release
|
- xserver 1.2.0 release
|
||||||
* Bug #9219: Return BadMatch when trying to name the backing
|
* Bug #9219: Return BadMatch when trying to name the backing
|
||||||
|
Loading…
Reference in New Issue
Block a user