Merge branch 'master' of git+ssh://git.freedesktop.org/git/xcb/libxcb
This commit is contained in:
commit
baae5826a6
57
NEWS
57
NEWS
|
@ -1,3 +1,60 @@
|
||||||
|
Release 1.1 (2007-11-04)
|
||||||
|
========================
|
||||||
|
|
||||||
|
This release requires xcb-proto 1.1, due to the addition of the
|
||||||
|
extension-multiword attribute to the XML schema.
|
||||||
|
|
||||||
|
This release contains several important bug fixes, summarized below. It
|
||||||
|
also contains a patch much like Novell's libxcb-sloppy-lock.diff.
|
||||||
|
Rationale from the commit message follows. The patch and this rationale
|
||||||
|
were authored by Jamey Sharp <jamey@minilop.net>, with agreement from
|
||||||
|
Josh Triplett <josh@freedesktop.org>.
|
||||||
|
|
||||||
|
I strongly opposed proposals like this one for a long time.
|
||||||
|
Originally I had a very good reason: libX11, when compiled to use
|
||||||
|
XCB, would crash soon after a locking correctness violation, so it
|
||||||
|
was better to have an informative assert failure than a mystifying
|
||||||
|
crash soon after.
|
||||||
|
|
||||||
|
It took some time for me to realize that I'd changed the libX11
|
||||||
|
implementation (for unrelated reasons) so that it could survive most
|
||||||
|
invalid locking situations, as long as it wasn't actually being used
|
||||||
|
from multiple threads concurrently.
|
||||||
|
|
||||||
|
The other thing that has changed is that most of the code with
|
||||||
|
incorrect locking has now been fixed. The value of the assert is
|
||||||
|
accordingly lower.
|
||||||
|
|
||||||
|
However, remaining broken callers do need to be fixed. That's why
|
||||||
|
libXCB will still noisily print a stacktrace (if possible) on each
|
||||||
|
assertion failure, even when assert isn't actually invoked to
|
||||||
|
abort() the program; and that's why aborting is still default. This
|
||||||
|
environment variable is provided only for use as a temporary
|
||||||
|
workaround for broken applications.
|
||||||
|
|
||||||
|
Enhancements:
|
||||||
|
* Print a backtrace, if possible, on locking assertion failures.
|
||||||
|
* Skip abort() on locking assertions if LIBXCB_ALLOW_SLOPPY_LOCK is set.
|
||||||
|
* xcb_poll_for_event: Return already-read events before reading again.
|
||||||
|
* Output a configuration summary at the end of ./configure.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
* Don't hold the xlib-xcb lock while sleeping: that allows deadlock.
|
||||||
|
* Allow unix:<screen> style display names again.
|
||||||
|
* Bug #9119: test xcb_popcount
|
||||||
|
* Fix unit tests for FreeBSD
|
||||||
|
* NetBSD doesn't have AI_ADDRCONFIG: use it only if it's available.
|
||||||
|
* Require libXau >= 0.99.2; earlier versions have a broken .pc file
|
||||||
|
* Use substitition variables in xcb-xinerama.pc.in
|
||||||
|
* Update autogen.sh to one that does objdir != srcdir
|
||||||
|
* Add tools/* and autogen.sh to EXTRA_DIST.
|
||||||
|
* Doxygen can now be fully disabled if desired.
|
||||||
|
|
||||||
|
Documentation improvements:
|
||||||
|
* Many fixes and updates to the tutorial.
|
||||||
|
* Iterators, requests, and replies get partial Doxygen documentation.
|
||||||
|
|
||||||
|
|
||||||
Release 1.0 (2006-11-23)
|
Release 1.0 (2006-11-23)
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
|
9
README
9
README
|
@ -1,11 +1,12 @@
|
||||||
About libxcb
|
About libxcb
|
||||||
============
|
============
|
||||||
|
|
||||||
libxcb provides an interface to the X Window System protocol, which replaces
|
libxcb provides an interface to the X Window System protocol, which
|
||||||
the current Xlib interface. It has several advantages over Xlib, including:
|
replaces the current Xlib interface. It has several advantages over
|
||||||
- size: small library and lower memory footprint
|
Xlib, including:
|
||||||
|
- size: small, simple library, and lower memory footprint
|
||||||
- latency hiding: batch several requests and wait for the replies later
|
- latency hiding: batch several requests and wait for the replies later
|
||||||
- direct protocol access: one-to-one mapping between interface and protocol
|
- direct protocol access: interface and protocol correspond exactly
|
||||||
- proven thread support: transparently access XCB from multiple threads
|
- proven thread support: transparently access XCB from multiple threads
|
||||||
- easy extension implementation: interfaces auto-generated from XML-XCB
|
- easy extension implementation: interfaces auto-generated from XML-XCB
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT([libxcb],
|
AC_INIT([libxcb],
|
||||||
1.0,
|
1.1,
|
||||||
[xcb@lists.freedesktop.org])
|
[xcb@lists.freedesktop.org])
|
||||||
AC_CONFIG_SRCDIR([xcb.pc.in])
|
AC_CONFIG_SRCDIR([xcb.pc.in])
|
||||||
AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
||||||
|
@ -30,7 +30,7 @@ fi
|
||||||
AC_SUBST(HTML_CHECK_RESULT)
|
AC_SUBST(HTML_CHECK_RESULT)
|
||||||
|
|
||||||
# Checks for pkg-config packages
|
# Checks for pkg-config packages
|
||||||
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.0)
|
PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.1)
|
||||||
NEEDED="pthread-stubs xau >= 0.99.2"
|
NEEDED="pthread-stubs xau >= 0.99.2"
|
||||||
PKG_CHECK_MODULES(NEEDED, $NEEDED)
|
PKG_CHECK_MODULES(NEEDED, $NEEDED)
|
||||||
|
|
||||||
|
|
|
@ -451,11 +451,6 @@ authorization from the authors.
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:variable>
|
</xsl:variable>
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="self::error|self::errorcopy">
|
|
||||||
<constant type="number" name="{xcb:xcb-prefix(concat('Bad', @name))}" value="{@number}" />
|
|
||||||
</xsl:when>
|
|
||||||
</xsl:choose>
|
|
||||||
<constant type="number" name="{xcb:xcb-prefix(@name)}" value="{@number}" />
|
<constant type="number" name="{xcb:xcb-prefix(@name)}" value="{@number}" />
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="self::event|self::error">
|
<xsl:when test="self::event|self::error">
|
||||||
|
|
|
@ -62,6 +62,9 @@ static int set_fd_flags(const int fd)
|
||||||
static int _xcb_xlib_init(_xcb_xlib *xlib)
|
static int _xcb_xlib_init(_xcb_xlib *xlib)
|
||||||
{
|
{
|
||||||
xlib->lock = 0;
|
xlib->lock = 0;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
xlib->sloppy_lock = (getenv("LIBXCB_ALLOW_SLOPPY_LOCK") != 0);
|
||||||
|
#endif
|
||||||
pthread_cond_init(&xlib->cond, 0);
|
pthread_cond_init(&xlib->cond, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -285,15 +288,33 @@ void _xcb_unlock_io(xcb_connection_t *c)
|
||||||
pthread_mutex_unlock(&c->iolock);
|
pthread_mutex_unlock(&c->iolock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond)
|
||||||
|
{
|
||||||
|
int xlib_locked = c->xlib.lock;
|
||||||
|
if(xlib_locked)
|
||||||
|
{
|
||||||
|
c->xlib.lock = 0;
|
||||||
|
pthread_cond_broadcast(&c->xlib.cond);
|
||||||
|
}
|
||||||
|
pthread_cond_wait(cond, &c->iolock);
|
||||||
|
if(xlib_locked)
|
||||||
|
{
|
||||||
|
while(c->xlib.lock)
|
||||||
|
pthread_cond_wait(&c->xlib.cond, &c->iolock);
|
||||||
|
c->xlib.lock = 1;
|
||||||
|
c->xlib.thread = pthread_self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count)
|
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, xlib_locked;
|
||||||
fd_set rfds, wfds;
|
fd_set rfds, wfds;
|
||||||
|
|
||||||
/* If the thing I should be doing is already being done, wait for it. */
|
/* If the thing I should be doing is already being done, wait for it. */
|
||||||
if(count ? c->out.writing : c->in.reading)
|
if(count ? c->out.writing : c->in.reading)
|
||||||
{
|
{
|
||||||
pthread_cond_wait(cond, &c->iolock);
|
_xcb_wait_io(c, cond);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +329,12 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
||||||
++c->out.writing;
|
++c->out.writing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xlib_locked = c->xlib.lock;
|
||||||
|
if(xlib_locked)
|
||||||
|
{
|
||||||
|
c->xlib.lock = 0;
|
||||||
|
pthread_cond_broadcast(&c->xlib.cond);
|
||||||
|
}
|
||||||
_xcb_unlock_io(c);
|
_xcb_unlock_io(c);
|
||||||
do {
|
do {
|
||||||
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
|
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
|
||||||
|
@ -318,6 +345,11 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
_xcb_lock_io(c);
|
_xcb_lock_io(c);
|
||||||
|
if(xlib_locked)
|
||||||
|
{
|
||||||
|
c->xlib.lock = 1;
|
||||||
|
c->xlib.thread = pthread_self();
|
||||||
|
}
|
||||||
|
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,7 +190,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
|
||||||
_xcb_lock_io(c);
|
_xcb_lock_io(c);
|
||||||
/* wait for other writing threads to get out of my way. */
|
/* wait for other writing threads to get out of my way. */
|
||||||
while(c->out.writing)
|
while(c->out.writing)
|
||||||
pthread_cond_wait(&c->out.cond, &c->iolock);
|
_xcb_wait_io(c, &c->out.cond);
|
||||||
|
|
||||||
request = ++c->out.request;
|
request = ++c->out.request;
|
||||||
/* send GetInputFocus (sync) when 64k-2 requests have been sent without
|
/* send GetInputFocus (sync) when 64k-2 requests have been sent without
|
||||||
|
@ -297,7 +297,7 @@ int _xcb_out_flush_to(xcb_connection_t *c, unsigned int request)
|
||||||
return _xcb_out_send(c, &vec_ptr, &count);
|
return _xcb_out_send(c, &vec_ptr, &count);
|
||||||
}
|
}
|
||||||
while(c->out.writing)
|
while(c->out.writing)
|
||||||
pthread_cond_wait(&c->out.cond, &c->iolock);
|
_xcb_wait_io(c, &c->out.cond);
|
||||||
assert(XCB_SEQUENCE_COMPARE(c->out.request_written, >=, request));
|
assert(XCB_SEQUENCE_COMPARE(c->out.request_written, >=, request));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,9 @@ static void xcb_xlib_printbt(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#define xcb_assert(x) do { if (!(x)) { xcb_xlib_printbt(); assert(x); } } while(0)
|
#define xcb_assert(c,x) do { if (!(x)) { xcb_xlib_printbt(); if (!(c)->xlib.sloppy_lock) assert(x); } } while(0)
|
||||||
#else
|
#else
|
||||||
#define xcb_assert(x)
|
#define xcb_assert(c,x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int xcb_get_request_sent(xcb_connection_t *c)
|
unsigned int xcb_get_request_sent(xcb_connection_t *c)
|
||||||
|
@ -70,7 +70,7 @@ unsigned int xcb_get_request_sent(xcb_connection_t *c)
|
||||||
void xcb_xlib_lock(xcb_connection_t *c)
|
void xcb_xlib_lock(xcb_connection_t *c)
|
||||||
{
|
{
|
||||||
_xcb_lock_io(c);
|
_xcb_lock_io(c);
|
||||||
xcb_assert(!c->xlib.lock);
|
xcb_assert(c, !c->xlib.lock);
|
||||||
c->xlib.lock = 1;
|
c->xlib.lock = 1;
|
||||||
c->xlib.thread = pthread_self();
|
c->xlib.thread = pthread_self();
|
||||||
_xcb_unlock_io(c);
|
_xcb_unlock_io(c);
|
||||||
|
@ -79,8 +79,8 @@ void xcb_xlib_lock(xcb_connection_t *c)
|
||||||
void xcb_xlib_unlock(xcb_connection_t *c)
|
void xcb_xlib_unlock(xcb_connection_t *c)
|
||||||
{
|
{
|
||||||
_xcb_lock_io(c);
|
_xcb_lock_io(c);
|
||||||
xcb_assert(c->xlib.lock);
|
xcb_assert(c, c->xlib.lock);
|
||||||
xcb_assert(pthread_equal(c->xlib.thread, pthread_self()));
|
xcb_assert(c, pthread_equal(c->xlib.thread, pthread_self()));
|
||||||
c->xlib.lock = 0;
|
c->xlib.lock = 0;
|
||||||
pthread_cond_broadcast(&c->xlib.cond);
|
pthread_cond_broadcast(&c->xlib.cond);
|
||||||
_xcb_unlock_io(c);
|
_xcb_unlock_io(c);
|
||||||
|
|
|
@ -130,6 +130,7 @@ int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread);
|
||||||
|
|
||||||
typedef struct _xcb_xlib {
|
typedef struct _xcb_xlib {
|
||||||
int lock;
|
int lock;
|
||||||
|
int sloppy_lock;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
} _xcb_xlib;
|
} _xcb_xlib;
|
||||||
|
@ -182,6 +183,7 @@ struct xcb_connection_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
void _xcb_conn_shutdown(xcb_connection_t *c);
|
void _xcb_conn_shutdown(xcb_connection_t *c);
|
||||||
|
void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond);
|
||||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: XCB SELinux
|
||||||
|
Description: XCB SELinux Extension
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Requires: xcb
|
||||||
|
Libs: -L${libdir} -lxcb-xselinux
|
||||||
|
Cflags: -I${includedir}
|
Loading…
Reference in New Issue