On 04/07/16 10:14 PM, Nathan Kidd wrote:
>
> This naive patch works around this specific case, though obviously it
> isn't a general solution:
>
> diff --git a/server/faker-xcb.cpp b/server/faker-xcb.cpp
> index f6f2d23..661cd1f 100644
> --- a/server/faker-xcb.cpp
> +++ b/server/faker-xcb.cpp
> @@ -224,7 +224,7 @@ xcb_generic_event_t
> *xcb_poll_for_event(xcb_connection_t *conn)
>
> TRY();
>
> - if((e=_xcb_poll_for_event(conn))!=NULL && fconfig.fakeXCB
> + if((e=_xcb_poll_for_event(conn))!=NULL && !isDead() &&
> fconfig.fakeXCB
> && vglfaker::getFakerLevel()==0)
> handleXCBEvent(conn, e);
>
Which exposes the below deadlock, caused by safeExit holding the global
lock while it tries to kill the X11Trans thread which is blocked waiting
for the global lock.
> Thread 2 (Thread 0x7fca26e2e700 (LWP 18636)):
> #0 0x0000003e9840e51d in __lll_lock_wait () from /lib64/libpthread.so.0
> #1 0x0000003e9840a136 in _L_lock_870 () from /lib64/libpthread.so.0
> #2 0x0000003e9840a02f in pthread_mutex_lock () from /lib64/libpthread.so.0
> #3 0x00007fca2bb67f6c in vglutil::CriticalSection::lock (this=0x1378060,
> errorCheck=false)
> at virtualgl/util/Mutex.cpp:186
> #4 0x00007fca2baf1b2d in isDead () at virtualgl/server/faker.h:76
> #5 0x00007fca2baf2eed in xcb_poll_for_event (conn=0x14c50a0)
> at virtualgl/server/faker-xcb.cpp:227
> #6 0x0000003e9b0426b8 in poll_for_event () from /lib64/libX11.so.6
> #7 0x0000003e9b043108 in _XReply () from /lib64/libX11.so.6
> #8 0x0000003e9b03ea2d in XSync () from /lib64/libX11.so.6
> #9 0x00007fca2bb0d61b in fbx_write (fb=0x14bff18, srcX_=0, srcY_=0, dstX_=0,
> dstY_=0, width_=800, height_=800)
> at virtualgl/util/fbx.c:510
> #10 0x00007fca2bb0bd7f in vglcommon::FBXFrame::redraw (this=0x14bfdf0)
> at virtualgl/common/Frame.cpp:659
> #11 0x00007fca2bb04428 in vglserver::X11Trans::run (this=0x14bfae0)
> at virtualgl/server/X11Trans.cpp:52
> #12 0x00007fca2bb68665 in vglutil::Thread::threadFunc (param=0x14bfae0)
> at virtualgl/util/Thread.cpp:92
> #13 0x0000003e98407ee5 in start_thread () from /lib64/libpthread.so.0
> #14 0x0000003e97cf4d1d in clone () from /lib64/libc.so.6
>
> Thread 1 (Thread 0x7fca2ba6c840 (LWP 18609)):
> #0 0x0000003e98409237 in pthread_join () from /lib64/libpthread.so.0
> #1 0x00007fca2bb6849f in vglutil::Thread::stop (this=0x14bfdd0)
> at virtualgl/util/Thread.cpp:52
> #2 0x00007fca2bb04cc7 in vglserver::X11Trans::~X11Trans (this=0x14bfae0,
> __in_chrg=<optimized out>)
> at virtualgl/server/X11Trans.h:37
> #3 0x00007fca2bb04eb8 in vglserver::X11Trans::~X11Trans (this=0x14bfae0,
> __in_chrg=<optimized out>)
> at virtualgl/server/X11Trans.h:42
> #4 0x00007fca2bb0102e in vglserver::VirtualWin::~VirtualWin (this=0x1458300,
> __in_chrg=<optimized out>)
> at virtualgl/server/VirtualWin.cpp:92
> ---Type <return> to continue, or q <return> to quit---
> #5 0x00007fca2bacab07 in vglserver::WindowHash::detach (this=0x1419fd0,
> entry=0x141a040)
> at virtualgl/server/WindowHash.h:153
> #6 0x00007fca2bacb898 in vglserver::Hash<char*, unsigned long,
> vglserver::VirtualWin*>::killEntry (
> this=0x1419fd0, entry=0x141a040) at virtualgl/server/Hash.h:137
> #7 0x00007fca2bacb93e in vglserver::Hash<char*, unsigned long,
> vglserver::VirtualWin*>::kill (this=0x1419fd0)
> at virtualgl/server/Hash.h:44
> #8 0x00007fca2bac93f5 in vglfaker::cleanup () at
> virtualgl/server/faker.cpp:56
> #9 0x00007fca2bac9461 in vglfaker::safeExit (retcode=1) at
> virtualgl/server/faker.cpp:71
> #10 0x00007fca2badf763 in glXMakeContextCurrent (dpy=0x1388680, draw=4194306,
> read=4194306, ctx=0x141a160)
> at virtualgl/server/faker-glx.cpp:1841
> #11 0x0000003ea5a27213 in fgSetWindow () from /lib64/libglut.so.3
> #12 0x0000003ea5a26154 in fgDestroyWindow () from /lib64/libglut.so.3
> #13 0x0000003ea5a22648 in glutMainLoopEvent () from /lib64/libglut.so.3
> #14 0x0000003ea5a22f89 in glutMainLoop () from /lib64/libglut.so.3
> #15 0x00000000004011bf in main ()
Avoided by additional patch, attached.
-Nathan
>From 94df43412295238ed9abdcf95c4a02e4bd8b9d49 Mon Sep 17 00:00:00 2001
From: Nathan Kidd <nk...@opentext.com>
Date: Thu, 7 Jul 2016 16:45:20 -0400
Subject: [PATCH] Avoid deadlock on shutdown
By not holding the globalMutex over potentially-blocking calls.
E.g. launch mesademo's singlebuffer app, close via window manager controls.
X11Trans thread does:
XSync -> xcb_poll_for_event -> isDead -> globalMutex.lock
Main app thread does make current on destroyed window:
glXMakeContextCurrent -> CATCH -> safeExit (does globalMutex.lock) ->
cleanup ... VirtualWin::~VirtualWin -> X11Trans::~X11Trans ... ->
vglutil::Thread::stop -> pthread_join
---
server/faker.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/server/faker.cpp b/server/faker.cpp
index d2d28b2..6282e0e 100644
--- a/server/faker.cpp
+++ b/server/faker.cpp
@@ -68,10 +68,12 @@ void safeExit(int retcode)
if(!deadYet)
{
deadYet=true;
+ globalMutex.unlock(false);
cleanup();
fconfig_deleteinstance();
}
- globalMutex.unlock(false);
+ else
+ globalMutex.unlock(false);
if(!shutdown) exit(retcode);
else pthread_exit(0);
}
--
2.1.4
------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
VirtualGL-Devel mailing list
VirtualGL-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-devel