XGrabServer() stops the processing of other display connections until a XUngrabServer() call is actually processed by the X server.
Now consider the following scenario: Thread 1: XGrabServer -> ... -> XUngrabServer -> Grab mutex A Thread 2: Grab mutex A -> Do something with another display connection
Before the XUngrabServer() request is actually processed by the X server, go on grabbing mutex A could trigger a lock because processing another display connection in thread 2 is blocked by thread 1 calling XGrabServer and thread 1 is blocked by thread 2 grabbing the same mutex. With thread 1 freezed, the XUngrabServer may never reach the X server, thus a deadlock.
By adding a XFlush() call right after XUngrabServer(), we avoid such a race condition.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v2: Fix a possible deadlock as described above. Supersede 171243~171245
dlls/winex11.drv/palette.c | 1 + dlls/winex11.drv/xrandr.c | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/dlls/winex11.drv/palette.c b/dlls/winex11.drv/palette.c index bba2253264..073761a5ee 100644 --- a/dlls/winex11.drv/palette.c +++ b/dlls/winex11.drv/palette.c @@ -480,6 +480,7 @@ static BOOL X11DRV_PALETTE_BuildSharedMap( const PALETTEENTRY *sys_pal_template palette_size = c_min + NB_RESERVED_COLORS;
XUngrabServer(gdi_display); + XFlush(gdi_display);
TRACE("adjusted size %i colorcells\n", palette_size); } diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 6bb2b18ce7..85da5efea3 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -419,6 +419,7 @@ static LONG xrandr12_set_current_mode( int mode ) if (status != RRSetConfigSuccess) { XUngrabServer( gdi_display ); + XFlush( gdi_display ); ERR("Failed to disable CRTC.\n"); pXRRFreeCrtcInfo( crtc_info ); pXRRFreeScreenResources( resources ); @@ -440,6 +441,7 @@ static LONG xrandr12_set_current_mode( int mode ) crtc_info->rotation, crtc_info->outputs, crtc_info->noutput );
XUngrabServer( gdi_display ); + XFlush( gdi_display );
pXRRFreeCrtcInfo( crtc_info ); pXRRFreeScreenResources( resources );