diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-10-11 17:16:39 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2010-10-11 22:36:42 +0200 |
commit | f8c6e1c42a16d6b00f058389ee79baef7c0ff5d4 (patch) | |
tree | c82997cbc93ad66dd0f37c7e8962360279fe407b /client/x11/red_drawable.cpp | |
parent | 57cea3235fd2c6a0b88ea67b4fbb350058ebe724 (diff) | |
download | spice-f8c6e1c42a16d6b00f058389ee79baef7c0ff5d4.tar.gz spice-f8c6e1c42a16d6b00f058389ee79baef7c0ff5d4.tar.xz spice-f8c6e1c42a16d6b00f058389ee79baef7c0ff5d4.zip |
spicec-x11: Put locks around xlib calls which wait for a reply
Since libX11-1.3.4 the multi-threading handling code of libX11 has been
changed, see:
http://cgit.freedesktop.org/xorg/lib/libX11/commit/?id=933aee1d5c53b0cc7d608011a29188b594c8d70b
This causes several issues. One of them is the display inside the
client not getting updated when there are no XEvents being generated,
this is caused by the following part of the referenced commit message:
Caveats:
- If one thread is waiting for events and another thread tries to read a reply,
both will hang until an event arrives. Previously, if this happened it might
work sometimes, but otherwise would trigger either an assertion failure or
a permanent hang.
We were depending on the otherwise behavior and apparently were lucky.
This can be seen by starting F14 in runlevel 3 and then doing startx
and not touching the mouse / keyb afterwards. Once you move the mouse
(generate an event you see the UI contents being updated but not before.
Another thing both I and Alon (iirc) have seen are hangs where 2
threads are stuck in XSync waiting for a reply simultaneously. This might
be related to libxcb version, according to the libX11 commit a libxcb
newer then 1.6 was needed, and my system had 1.5 at the time I saw this
after updating to libxcb 1.7 I can no longer reproduce.
This patch tackles both problems (and is needed for the 1st one
indepently of the 2nd one possibly being fixed) by adding XLockDisplay
calls around all libX11 calls which wait for a reply or an event.
Diffstat (limited to 'client/x11/red_drawable.cpp')
-rw-r--r-- | client/x11/red_drawable.cpp | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp index 327028b9..e7151eda 100644 --- a/client/x11/red_drawable.cpp +++ b/client/x11/red_drawable.cpp @@ -216,7 +216,6 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest, dest->source.x_drawable.gc, source->pixmap.x_image, src_x, src_y, area.left + offset.x, area.top + offset.y, area.right - area.left, area.bottom - area.top, false); - XSync(XPlatform::get_display(), 0); } else { XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, dest->source.x_drawable.gc, source->pixmap.x_image, src_x, @@ -242,7 +241,6 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest, dest->source.x_drawable.gc, image, 0, 0, area.left + offset.x, area.top + offset.y, area.right - area.left, area.bottom - area.top, false); - XSync(XPlatform::get_display(), 0); } else { XPutImage(XPlatform::get_display(), dest->source.x_drawable.drawable, dest->source.x_drawable.gc, image, @@ -252,6 +250,7 @@ static inline void copy_to_drawable_from_pixmap(const RedDrawable_p* dest, free_temp_image(image, shminfo, pixman_image); } + XFlush(XPlatform::get_display()); } static inline void copy_to_x_drawable(const RedDrawable_p* dest, @@ -628,6 +627,7 @@ static inline void fill_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb Drawable drawable = dest->source.x_drawable.drawable; GC gc = dest->source.x_drawable.gc; + XLockDisplay(XPlatform::get_display()); Colormap color_map = DefaultColormap(XPlatform::get_display(), DefaultScreen(XPlatform::get_display())); XColor x_color; @@ -639,6 +639,7 @@ static inline void fill_drawable(RedDrawable_p* dest, const SpiceRect& area, rgb if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) { LOG_WARN("color map failed"); } + XUnlockDisplay(XPlatform::get_display()); XGCValues gc_vals; gc_vals.foreground = x_color.pixel; @@ -724,6 +725,7 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg Drawable drawable = dest->source.x_drawable.drawable; GC gc = dest->source.x_drawable.gc; + XLockDisplay(XPlatform::get_display()); Colormap color_map = DefaultColormap(XPlatform::get_display(), DefaultScreen(XPlatform::get_display())); XColor x_color; @@ -735,6 +737,7 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg if (!XAllocColor(XPlatform::get_display(), color_map, &x_color)) { LOG_WARN("color map failed"); } + XUnlockDisplay(XPlatform::get_display()); XGCValues gc_vals; gc_vals.foreground = x_color.pixel; |