Age | Commit message (Collapse) | Author |
|
The reason strings returned by the server don't all include a newline,
so make sure we add one to avoid confusing clients. Xlib used to do
this before it delegated that work to libxcb.
Fixes #34
Signed-off-by: Julien Cristau <jcristau@debian.org>
|
|
There are at least two bugs in the previous implementation:
- If an early iovec is partially written, there can be a gap of missing
data (as a later iovec will be started before the early iovec is
completed).
- If a late iovec returns WSAEWOULDBLOCK, *vector and *count are not
updated, leading to a re-send of the entire request.
Move the *vector update into the send() loop to update piecemeal as
individual iovecs are sent.
Example program that demonstrates the issue (this program should run
forever after these bugs have been fixed):
#include <stdio.h>
#include <stdlib.h>
#include "xcb.h"
// Non-cryptographic random number generator from http://burtleburtle.net/bob/rand/smallprng.html
// because Microsoft's random number generators either have a too small RAND_MAX or are too slow
typedef struct ranctx { uint32_t a; uint32_t b; uint32_t c; uint32_t d; } ranctx;
static uint32_t ranval(ranctx *x);
static void raninit(ranctx *x, uint32_t seed);
#define MAX_PROP_LEN (128 * 1024)
int main(int argc, char *argv[]) {
uint32_t seed = 0x12345678;
if (argc > 1) {
seed = strtoul(argv[1], NULL, 0);
}
ranctx ran;
raninit(&ran, seed);
xcb_connection_t *c = xcb_connect(NULL, NULL);
if (!c || xcb_connection_has_error(c)) {
printf("Cannot connect to $DISPLAY\n");
return 1;
}
const xcb_setup_t *setup = xcb_get_setup(c);
char *buf = malloc(MAX_PROP_LEN + 8); // plus a bit of slack so we can run random values off the end
if (!buf) {
printf("oom\n");
return 1;
}
for (uint32_t i=0; i < (MAX_PROP_LEN + 3) / 4; i++) {
((uint32_t *)buf)[i] = ranval(&ran);
}
xcb_window_t win = xcb_generate_id(c);
xcb_create_window(c, 0, win, xcb_setup_roots_iterator(setup).data[0].root, 0, 0, 1, 1, 0,
XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, NULL);
printf("Created window 0x%X\n", win);
for (;;) {
xcb_flush(c);
xcb_generic_event_t *ev = xcb_poll_for_event(c);
if (ev) {
if (ev->response_type == 0) {
xcb_generic_error_t *err = (xcb_generic_error_t *)ev;
printf("Unexpected X Error %d\n", err->error_code);
printf(" Sequence %d\n", err->sequence);
printf(" Resource ID 0x%X\n", err->resource_id);
printf(" Opcode: %d.%d\n", err->major_code, err->minor_code);
return 1;
}
printf("Unexpected X Event %d\n", ev->response_type);
return 1;
}
uint32_t siz = ranval(&ran) % MAX_PROP_LEN + 1;
xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, XCB_ATOM_STRING, XCB_ATOM_STRING, 8, siz, buf);
}
return 0;
}
#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))
static uint32_t ranval(ranctx *x) {
uint32_t e = x->a - rot(x->b, 27);
x->a = x->b ^ rot(x->c, 17);
x->b = x->c + x->d;
x->c = x->d + e;
x->d = e + x->a;
return x->d;
}
static void raninit(ranctx *x, uint32_t seed) {
uint32_t i;
x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
for (i = 0; i<20; ++i) {
(void)ranval(x);
}
}
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Notable changes: Protect include of unistd.h (and other POSIX headers).
Use SOCKET (which is larger than int) and closesocket (because close is
not compatible) for sockets. Use <stdint.h>'s intptr_t instead of the
non-portable ssize_t.
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Returns raw byte counts that have been read or written to the
xcb_connection_t.
I found it very useful when developing a high level widget toolkit, to
track down inefficient/sub-optimum code that generates a lot of X
protocol traffic.
Signed-off-by: Sam Varshavchik <mrsam@courier-mta.com>
|
|
The documentation doesn't mention it and it's unlikely that a lot of code out
there handles this case correctly. So, instead of returning NULL, let
xcb_get_setup() return a pointer to a static, invalid, all-zero setup
information structure.
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
There is no technical reason why xcb_get_setup() and xcb_get_file_descriptor()
shouldn't work on non-static error connections. They cannot be used for many
useful things, but at least they work.
This works around bugs in lots of programs out there which assume that
xcb_get_setup() does not return NULL and which just happily dereference the
results. Since xcb_connect() never returns NULL, it's a bit weird that
xcb_get_setup() can do so. xcb_get_file_descriptor() is just modified since this
can be done here equally easily and because the fd isn't closed until the final
xcb_disconnect() on the error connection.
Non-static error connections are connections which entered an error state after
xcb_connect() succeeded. If something goes wrong in establishing a connection,
xcb_connect() will return a static error connection which doesn't have the
fields used here.
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
Code can be simplified if the deallocation functions can always be called in
cleanup code. So if you have some code that does several things that can go
wrong, one of which is xcb_connect(), after this change, the xcb_connection_t*
variable can be initialized to NULL and xcb_disconnect() can always be called on
the connection object.
References: http://lists.freedesktop.org/archives/xcb/2013-September/008659.html
Signed-off-by: Uli Schlachter <psychon@znc.in>
Reviewed-by: Julien Cristau <jcristau@debian.org>
|
|
There are two kind of error connections in XCB. First, if something goes wrong
while the connection is being set up, _xcb_conn_ret_error() is used to return a
static connection in an error state. If something goes wrong later,
_xcb_conn_shutdown() is used to set c->has_error.
This is important, because the static object that _xcb_conn_ret_error() returns
must not be freed, while the dynamically allocated objects that go through
_xcb_conn_shutdown() must obviously be properly deallocated.
This used to work correctly, but in 769acff0da8, xcb_disconnect() was made to
ignore all connections in an error state completely. Fix this by only ignoring
the few static error connections that we have.
This was tested with the following hack:
xcb_connection_t *c = xcb_connect(NULL, NULL);
close(xcb_get_file_descriptor(c));
xcb_discard_reply(c, xcb_get_input_focus(c).sequence);
xcb_flush(c);
xcb_disconnect(c);
Valgrind confirms that xcb has a memory leak before this patch that this patch
indeed fixes.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Reviewed-by: Julien Cristau <jcristau@debian.org>
|
|
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
If xcb_connect() fails, it doesn't return NULL. Instead, it always
returns an xcb_connection_t*, and the user should check for errors with
the xcb_connection_has_error() function. What this function does is
check if conn->has_error contains a non-zero error code, and returns it.
If an error did occur, xcb doesn't actually return a full
xcb_connection_t though, it just returns (xcb_connection_t *)
error_code. Since the 'has_error' field is the first, it is still
possible to check conn->has_error.
That last trick was not immediately obvious to me, so add some guiding
comments. This also ensures no one obliviously rearranges the struct.
Signed-off-by: Ran Benita <ran234@gmail.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
A char array on the stack is not guaranteed to have more than byte alignment.
This means that casting it to a 'struct cmsghdr' and accessing its members
may result in unaligned access. This will generate SIGBUS on struct
alignment architectures like OpenBSD/sparc64. The canonical solution is to
use a union to force proper alignment.
Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
Use these instead of computing the values directly so that it might
work on BSD or other non-Linux systems
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
This uses sendmsg to transmit file descriptors from the application to
the X server
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-By: Uli Schlachter <psychon@znc.in>
|
|
It seems like POLLIN is specified as equivalent to POLLRDNORM | POLLRDBAND. Some
systems (e.g. QNX and HP-UX) take this literaly and have POLLIN defined as the
above bit combination. Other systems (e.g. Linux) have POLLIN as just a single
bit.
This means that if no out-of-band data is available (which should never be the
case), the result of poll() will not fulfil (fd.revents & POLLIN) == POLLIN on
QNX, because the POLLRDBAND bit is not set.
In other words, even though poll() signaled that the fd is readable, xcb would
not read from the file descriptor.
Fix this by checking if any bits from POLLIN are set in the result of poll(),
instead of all of them.
(This change was independently done by seanb@qnx.com as well)
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=38001
Acked-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
This fixes a deadlock which was seen in-the-wild with wine.
It could happen that two threads tried to read from the socket at the same time
and one of the thread got stuck inside of poll()/select().
The fix works by making sure that the writing thread doesn't steal the reading
thread's reply.
Debugged-by: Erich Hoover <ehoover@mines.edu>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54671
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
This allows an application to do a scatter/gather operation on a large
image buffer to avoid the extra memcpy.
Use autoconf to use UIO_MAXIOV where IOV_MAX is not available (and the
POSIX minimum of 16 where neither are available).
Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Matches the behaviour of Xlib - if you set DISPLAY to :0.1 but only have
one screen, closes connection and returns error.
This introduces a new connection error code:
XCB_CONN_CLOSED_INVALID_SCREEN
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
|
|
Allows configure to set defines such as _POSIX_SOURCE in config.h
that affect functions exposed by system headers and get consistent
results across all the source files.
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
The alternative is to use these in every WIN32 application which uses xcb. Doing
it this way should be safe, as, according to MSDN, "There must be a call to
WSACleanup for each successful call to WSAStartup. Only the final WSACleanup
function call performs the actual cleanup. The preceding calls simply decrement
an internal reference count"
(We should probably also include ws2_32 in Libs.private for libxcb, as anything
which links with libxcb will also need that, but there seems to be some pkg-config
issues to resolve first...)
v2: Check for errors so WSAStartup()/WSACleanup() uses are balanced
v3: Use same indentation style as surrounding code
Reviewed-by: Peter Harris <pharris@opentext.com>
Signed-off-by: Julien Danjou <julien@danjou.info>
|
|
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=41443
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=42304
I have added more xcb connection error states at xcb.h header.
Also I have removed global error_connection variable, and added
an interface that returns connection error state.
TBD:
I will segregate errors states in a separate header file and try to
provide more precise error states, in future. Also I will give patch
for libX11, in that patch xcb_connection_t::has_error will be passed
to default io handler of libX11. This value can then be used for
displaying error messages.
Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi>
Reviewed-by: Uli Schlachter <psychon@znc.in>
Signed-off-by: Arvind Umrao <arvind.umrao@oracle.com>
|
|
Solves compiler warning on Solaris:
"xcb_conn.c", line 304: warning: implicit function declaration: shutdown
Also provides system definition of SHUT_RDWR on Solaris 11.
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Jamey Sharp <jamey@minilop.net>
|
|
Windows' file handles have never been small or consecutive, so Windows'
select has always been implemented the same way as everyone else's poll.
On Windows, FD_SETSIZE is the size of the poll array, not the maximum
SOCKET number.
Signed-off-by: Peter Harris <git@peter.is-a-geek.org>
|
|
In support of this, consolidate the two static error_connection
definitions into one so we don't try to free the static out-of-memory
error_connection.
Commit by Josh Triplett and Jamey Sharp.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
|
|
If a client calls close(2) on the connection's file descriptor and then
flushes writes, libxcb causes a hang in the client.
Any flush eventually calls _xcb_out_send() with has the following loop:
while(ret && *count)
ret = _xcb_conn_wait(c, &c->out.cond, vector, count);
_xcb_conn_wait(), if built with USE_POLL, gets the POLLNVAL error. It only
checks for POLLIN and POLLOUT though, ignoring the error. Return value is 1,
count is unmodified, leaving us with an endless loop and a client hang.
XTS testcase Xlib3/XConnectionNumber triggers this bug. It creates a display
connection, closes its file descriptor, tries to send a no-op, and then expects
an error.
http://cgit.freedesktop.org/xorg/test/xts/tree/xts5/Xlib3/XConnectionNumber.m
If poll returned POLLHUP or POLLERR, we might see the same result.
If poll returns any event we didn't ask for, this patch causes
_xcb_conn_shutdown() to be invoked and an error returned. This matches the
behaviour if select(2) is used instead of poll(2): select(2) returns -1 and
EBADF for an already closed file descriptor.
I believe this fix both is safe and will handle any similar error. POSIX says
that the only bits poll is permitted to set in revents are those bits that were
set in events, plus POLLHUP, POLLERR, and POLLNVAL. So if we see any flags we
didn't ask for then something has gone wrong.
Patch inspired by earlier proposals from Peter Hutterer and Aaron
Plattner--thanks!
Reported-by: Peter Hutterer <peter.hutterer@who-t.net>
Reported-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Aaron Plattner <aplattner@nvidia.com>
Cc: Peter Hutterer <peter.hutterer@who-t.net>
Cc: Dan Nicholson <dbn.lists@gmail.com>
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Conflicts:
src/xcb_conn.c
src/xcb_util.c
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Fixes the X Test Suite's XCloseDisplay-6 test, which has this (admittedly
ridiculous) behavior:
1. Create a window w.
2. Open two display connections, dpy1, and dpy2.
3. Grab the server using dpy1.
4. Fork.
5 (child). XSetProperty on w using dpy2.
5 (parent). Verify that no event was recieved on dpy1.
6 (parent). XCloseDisplay(dpy1).
6 (child). Verify that an event was received on dpy2.
It was failing because at step 6 (child), the server had not actually ungrabbed
yet because the file descriptor for dpy1 was still open in the child process.
Shutting down the socket during XCloseDisplay matches the behavior of non-XCB
Xlib, which calls shutdown() from _X11TransSocketDisconnect.
Thanks to Julien Cristau for noticing this.
Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Peter Harris <pharris@opentext.com>
|
|
Signed-off-by: Jamey Sharp <jamey@minilop.net>
|
|
_xcb_out_send needs _xcb_conn_wait to store back its progress so it can
be reinvoked to pick up where it left off---but then _xcb_out_send
guarantees that it leaves either an empty output vector or a shut-down
connection, so *its* callers never care how much progress was made.
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Reviewed-by: Josh Triplett <josh@freedesktop.org>
|
|
Depending on the process file limit, a file descriptor can be larger
than the capacity of fd_set. There is no portable way to create a
large enough fd_set at run-time. So we just fail if the file descriptor
number is too high and poll() is not available.
Reviewed-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Julien Danjou <julien@danjou.info>
|
|
that.Replaced one instance ofWIN32 with _WIN32 in each xcb_in.c and xcb_conn.c
|
|
|
|
Signed-off-by: Julien Danjou <julien@danjou.info>
|
|
Signed-off-by: Julien Danjou <julien@danjou.info>
|
|
These functions are once again a single pthread call, so just make that
call directly.
|
|
|
|
Signed-off-by: Julien Danjou <julien@danjou.info>
|
|
With this patch, `ico -threads 2` runs without deadlock.
Many thanks to Christoph Pfister <christophpfister@gmail.com> for
pointing out the problem, providing detailed analyses, explaining it to
me repeatedly until I understood what was going on, and proposing and
reviewing possible solutions.
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Acked-by: Christoph Pfister <christophpfister@gmail.com>
|
|
This parallels the _xcb_lock_io and _xcb_unlock_io factoring.
|
|
But do still print a full backtrace, on platforms where that's
supported.
This commit follows the spirit of Novell's libxcb-sloppy-lock.diff.
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.
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Acked-by: Josh Triplett <josh@freedesktop.org>
|
|
|
|
lock just for libX11.
|
|
|
|
Rename API to follow a new naming convention:
* XCB_CONSTANTS_UPPERCASE_WITH_UNDERSCORES
* xcb_functions_lowercase_with_underscores
* xcb_types_lowercase_with_underscores_and_suffix_t
* expand all abbreviations like "req", "rep", and "iter"
Word boundaries for the names in the protocol descriptions fall:
* Wherever the protocol descriptions already have an underscore
* Between a lowercase letter and a subsequent uppercase letter
* Before the last uppercase letter in a string of uppercase letters followed
by a lowercase letter (such as in LSBFirst between LSB and First)
* Before and after a string of digits (with exceptions for sized types like
xcb_char2b_t and xcb_glx_float32_t to match the stdint.h convention)
Also fix up some particular naming issues:
* Rename shape_op and shape_kind to drop the "shape_" prefix, since otherwise
these types end up as xcb_shape_shape_{op,kind}_t.
* Remove leading underscores from enums in the GLX protocol description,
previously needed to ensure a word separator, but now redundant.
This renaming breaks code written for the previous API naming convention. The
scripts in XCB's tools directory will convert code written for the old API to
use the new API; they work well enough that we used them to convert the
non-program-generated code in XCB, and when run on the old program-generated
code, they almost exactly reproduce the new program-generated code (modulo
whitespace and bugs in the old code generator).
Authors: Vincent Torri, Thomas Hunger, Josh Triplett
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Setup*. Provide deprecated backwards-compatability functions and typedefs for the old names, to be removed before 1.0.
|