From eca5dee9e7a8dea1edba4d10b60444ac0e884139 Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 20 Mar 2011 16:32:44 +0000 Subject: xserver libX11 libxcb pixman mesa git update 20 Mar 2011 --- libxcb/src/c-client.xsl | 1551 ----------------------------------------------- libxcb/src/xcb.h | 35 ++ libxcb/src/xcb_in.c | 119 ++-- libxcb/src/xcbint.h | 2 + 4 files changed, 117 insertions(+), 1590 deletions(-) delete mode 100644 libxcb/src/c-client.xsl (limited to 'libxcb/src') diff --git a/libxcb/src/c-client.xsl b/libxcb/src/c-client.xsl deleted file mode 100644 index a15d824a1..000000000 --- a/libxcb/src/c-client.xsl +++ /dev/null @@ -1,1551 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { "" } - - - - - - - - - - xcb - - _ - - - - - - - - - - - - - _ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - char - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ - - - - - - - - - - - _ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Multiple definitions of type " - - " found. - - - - - - - - - - - - No definitions of type " - - " found - - , and it is not a known core type - - . - - - - - - - - - - - - - - - - xcb_void - - - _cookie_t - - - - - - - - - _checked - _unchecked - - - - - - - /** - * Delivers a request to the X server - * @param c The connection - * @return A cookie - * - * Delivers a request to the X server. - * - - * This form can be used only if the request will not cause - * a reply to be generated. Any returned error will be - * saved for handling by xcb_request_check(). - - - * This form can be used only if the request will cause - * a reply to be generated. Any returned error will be - * placed in the event queue. - - */ - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** - * Return the reply - * @param c The connection - * @param cookie The cookie - * @param e The xcb_generic_error_t supplied - * - * Returns the reply of the request asked by - * - * The parameter @p e supplied to this function must be NULL if - * _unchecked(). is used. - * Otherwise, it stores the error if any. - * - * The returned value must be freed by the caller using free(). - */ - - - - - - - - return (_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); - - - - - - - - - - - - - - union - - - - - - - - - - - - _event_t - - - _error_t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _t - - - - - - _t - - - - - - - - - - - - - - - - - - - - - - - - - - - _t - - - - - - - - - - - _t - - - - - - true - - - - - - - - - - - - - - - length - 2 - - - - - - - - - Encountered a list with no length expresssion outside a request or reply. - - - - - - - - - - - - - - _t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _t - - - - - - - - - - - - - - - - - - const - - - _t - - * - - - - - - - - - - - - - - _t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Unions must be fixed length. - - - - - - - - - - - - - - - - - - - - - - - static const xcb_protocol_request_t xcb_req = { - - /* count */ , - /* ext */ - - & - - _id - - 0 - , - /* opcode */ , - /* isvoid */ - - }; - - - struct iovec xcb_parts[]; - xcb_ret; - xcb_out; - - - - xcb_out.pad0 = 0; - - - - - xcb_parts[2].iov_base = (char *) &xcb_out; - xcb_parts[2].iov_len = sizeof(xcb_out); - xcb_parts[3].iov_base = 0; - xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; - - - xcb_parts[].iov_base = (char *) ; - xcb_parts[].iov_len = - - * sizeof( - - - char - - - - - - ) - ; - xcb_parts[].iov_base = 0; - xcb_parts[].iov_len = -xcb_parts[].iov_len & 3; - - - xcb_ret.sequence = xcb_send_request(c, - XCB_REQUEST_CHECKED - 0 - , xcb_parts + 2, &xcb_req); - return xcb_ret; - - - - - xcb_out. - - = - - ; - - - - - - xcb_out. - - = - - ; - - - - - - - xcb_out.pad = 0; - memset(xcb_out.pad, 0, ); - - - - - - - - - - - - - - - - - R + 1 - - - - _end(__iterator(R)) - - - __end(R) - - - - - - - - - - - - - - - - - return ( *) (); - - - xcb_generic_iterator_t prev = ; - return ( *) ((char *) prev.data + XCB_TYPE_PAD(, prev.index)); - - - - - - - return - - ; - - - - - - _iterator_t i; - - - i.data = ( *) (); - - - xcb_generic_iterator_t prev = ; - i.data = ( *) ((char *) prev.data + XCB_TYPE_PAD(, prev.index)); - - - i.rem = - - ; - i.index = (char *) i.data - (char *) R; - return i; - - - - - - char - - - - - - xcb_generic_iterator_t i; - - - i.data = (( *) ()) + ( - - ); - - - xcb_generic_iterator_t child = ; - i.data = (( *) child.data) + ( - - ); - - - i.rem = 0; - i.index = (char *) i.data - (char *) R; - return i; - - - - - - - /** - * Get the next element of the iterator - * @param i Pointer to a _iterator_t - * - * Get the next element in the iterator. The member rem is - * decreased by one. The member data points to the next - * element. The member index is increased by sizeof(_t) - */ - - - - _t *R = i->data; - xcb_generic_iterator_t child = ; - --i->rem; - i->data = (_t *) child.data; - i->index = child.index; - - - --i->rem; - ++i->data; - i->index += sizeof(_t); - - - - - /** - * Return the iterator pointing to the last element - * @param i An _iterator_t - * @return The iterator pointing to the last element - * - * Set the current element in the iterator to the last element. - * The member rem is set to 0. The member data points to the - * last element. - */ - - xcb_generic_iterator_t ret; - - - while(i.rem > 0) - - _next(&i); - - ret.data = i.data; - ret.rem = i.rem; - ret.index = i.index; - - - ret.data = i.data + i.rem; - ret.index = i.index + ((char *) ret.data - (char *) i.data); - ret.rem = 0; - - - return ret; - - - - - - - - Error: This stylesheet requires the EXSL node-set extension. - - - - Error: Parameter "mode" must be "header" or "source". - - - - - - - ___H - -/* - * This file generated automatically from -.xml by c-client.xsl using XSLT. - * Edit at your peril. - */ - - -/** - * @defgroup XCB__API XCB API - * @brief XCB Protocol Implementation. - - * @{ - **/ - - - -#ifndef -#define - -#include "xcb.h" - -#include ".h" - - - - - - - - - #define XCB__MAJOR_VERSION - - #define XCB__MINOR_VERSION - - - - - - - - - -#include <string.h> - -#include <assert.h> -#include "xcbext.h" -#include ".h" - - - - - - - -#endif - -/** - * @} - */ - - - - - - - - - /** Opcode for . */ - - #define - - - - - - - - - - - extern - - const char - - [] - - = " - - " - - ; - - - - - - extern - - - - = - - - ; - - - - - - - - - typedef - - - - ; - - - - - - - - - - - - - /** - * @brief - **/ - - typedef - struct - - - { - - - - - - - ; /**< */ - - - } - - ; - - - - - - - - typedef enum - - { - - - , - - - - - - - = - - - - - - - -} ; - - - - - - - - - - - - - - - - - -/***************************************************************************** - ** - ** - - - ** - - - - - ** @param - - - - - - - - ** @returns - ** - *****************************************************************************/ - - - - - - - - , - - - - - - - - - - - - /**< */ - - - - - ) - - ; - - - - - -{ - - - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ( - - - - - - - - - - ) - - - - (1 << - - ) - - - - - - ( - - - - - - - - - - - ) - - - - - - Invalid element in expression: - - - - - - - - - - - - - - - - - [ - - ] - - - - - - - - - - - pad - - - - - - [ - - ] - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - diff --git a/libxcb/src/xcb.h b/libxcb/src/xcb.h index f781e87f9..b1bab44da 100644 --- a/libxcb/src/xcb.h +++ b/libxcb/src/xcb.h @@ -271,6 +271,41 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c); */ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c); +/** + * @brief Returns the next event or error that precedes the given request. + * @param c: The connection to the X server. + * @param request: The limiting sequence number. + * @return The next event from the server. + * + * Returns the next event or error with a sequence number less than or + * equal to the given sequence number, or returns NULL if no such event can + * ever arrive. Blocks until either a suitable event or error arrive, or a + * response arrives that proves no such event is coming, or an I/O error + * occurs. + * + * After processing a request, the X server sends responses in a specific + * order. First come any events that the request generated, then any + * replies for the request, then the error response if there is one. After + * that, the server may spontaneously send more events with the same + * sequence number, which are not related to that request. + * + * This function will always return events from the pre-reply phase of the + * specified request. It may also return events from the unrelated + * post-reply stream, as long as they have the same sequence number. + * + * This function is useful for callers that need to process responses in + * wire-order. + * + * Implementation note: You cannot currently use this function to ensure + * that you process responses in exactly wire-order, because depending on + * the sequence of calls you make and the timing of server responses, + * post-reply events with the same sequence number may be returned as part + * of the pre-reply event stream, even though they were separated by a + * reply or error. In practice this kind of error is unlikely to matter, + * but it may be fixed in the future. + */ +xcb_generic_event_t *xcb_wait_for_event_until(xcb_connection_t *c, unsigned int request); + /** * @brief Return the error for a request, or NULL if none can ever arrive. * @param c: The connection to the X server. diff --git a/libxcb/src/xcb_in.c b/libxcb/src/xcb_in.c index 1ad51e331..a49efd5db 100644 --- a/libxcb/src/xcb_in.c +++ b/libxcb/src/xcb_in.c @@ -57,6 +57,7 @@ #endif struct event_list { + uint64_t sequence; xcb_generic_event_t *event; struct event_list *next; }; @@ -80,6 +81,17 @@ typedef struct reader_list { struct reader_list *next; } reader_list; +static void remove_finished_readers(reader_list **prev_reader, uint64_t completed) +{ + while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed)) + { + /* If you don't have what you're looking for now, you never + * will. Wake up and leave me alone. */ + pthread_cond_signal((*prev_reader)->data); + *prev_reader = (*prev_reader)->next; + } +} + static int read_packet(xcb_connection_t *c) { xcb_generic_reply_t genrep; @@ -114,7 +126,7 @@ static int read_packet(xcb_connection_t *c) c->in.current_reply = 0; c->in.current_reply_tail = &c->in.current_reply; } - c->in.request_completed = c->in.request_read - 1; + c->in.request_completed = c->in.event_responses_completed = c->in.request_read - 1; } while(c->in.pending_replies && @@ -129,7 +141,12 @@ static int read_packet(xcb_connection_t *c) } if(genrep.response_type == XCB_ERROR) - c->in.request_completed = c->in.request_read; + c->in.request_completed = c->in.event_responses_completed = c->in.request_read; + else if(genrep.response_type == XCB_REPLY) + c->in.event_responses_completed = c->in.request_read; + + remove_finished_readers(&c->in.readers, c->in.request_completed); + remove_finished_readers(&c->in.event_readers, c->in.event_responses_completed); } if(genrep.response_type == XCB_ERROR || genrep.response_type == XCB_REPLY) @@ -194,7 +211,6 @@ static int read_packet(xcb_connection_t *c) if( genrep.response_type == XCB_REPLY || (genrep.response_type == XCB_ERROR && pend && (pend->flags & XCB_REQUEST_CHECKED))) { - reader_list *reader; struct reply_list *cur = malloc(sizeof(struct reply_list)); if(!cur) { @@ -206,17 +222,8 @@ static int read_packet(xcb_connection_t *c) cur->next = 0; *c->in.current_reply_tail = cur; c->in.current_reply_tail = &cur->next; - for(reader = c->in.readers; - reader && - XCB_SEQUENCE_COMPARE(reader->request, <=, c->in.request_read); - reader = reader->next) - { - pthread_cond_signal(reader->data); - if(reader->request == c->in.request_read) - { - break; - } - } + if(c->in.readers && c->in.readers->request == c->in.request_read) + pthread_cond_signal(c->in.readers->data); return 1; } @@ -228,11 +235,15 @@ static int read_packet(xcb_connection_t *c) free(buf); return 0; } + event->sequence = c->in.request_read; event->event = buf; event->next = 0; *c->in.events_tail = event; c->in.events_tail = &event->next; - pthread_cond_signal(&c->in.event_cond); + if(c->in.event_readers) + pthread_cond_signal(c->in.event_readers->data); + else + pthread_cond_signal(&c->in.event_cond); return 1; /* I have something for you... */ } @@ -356,6 +367,26 @@ static int poll_for_reply(xcb_connection_t *c, uint64_t request, void **reply, x return 1; } +static void insert_reader(reader_list **prev_reader, reader_list *reader, uint64_t request, pthread_cond_t *cond) +{ + while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request)) + prev_reader = &(*prev_reader)->next; + reader->request = request; + reader->data = cond; + reader->next = *prev_reader; + *prev_reader = reader; +} + +static void remove_reader(reader_list **prev_reader, reader_list *reader) +{ + while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, reader->request)) + if(*prev_reader == reader) + { + *prev_reader = (*prev_reader)->next; + break; + } +} + static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e) { void *ret = 0; @@ -365,35 +396,14 @@ static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_e { pthread_cond_t cond = PTHREAD_COND_INITIALIZER; reader_list reader; - reader_list **prev_reader; - - for(prev_reader = &c->in.readers; - *prev_reader && - XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request); - prev_reader = &(*prev_reader)->next) - { - /* empty */; - } - reader.request = request; - reader.data = &cond; - reader.next = *prev_reader; - *prev_reader = &reader; + + insert_reader(&c->in.readers, &reader, request, &cond); while(!poll_for_reply(c, request, &ret, e)) if(!_xcb_conn_wait(c, &cond, 0, 0)) break; - for(prev_reader = &c->in.readers; - *prev_reader && - XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request); - prev_reader = &(*prev_reader)->next) - { - if(*prev_reader == &reader) - { - *prev_reader = (*prev_reader)->next; - break; - } - } + remove_reader(&c->in.readers, &reader); pthread_cond_destroy(&cond); } @@ -540,6 +550,35 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c) return ret; } +static xcb_generic_event_t *get_event_until(xcb_connection_t *c, uint64_t request) +{ + if(c->in.events && XCB_SEQUENCE_COMPARE(c->in.events->sequence, <=, request)) + return get_event(c); + return 0; +} + +xcb_generic_event_t *xcb_wait_for_event_until(xcb_connection_t *c, unsigned int request) +{ + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + reader_list reader; + xcb_generic_event_t *ret; + if(c->has_error) + return 0; + pthread_mutex_lock(&c->iolock); + + insert_reader(&c->in.event_readers, &reader, widen(c, request), &cond); + + while(!(ret = get_event_until(c, reader.request)) && XCB_SEQUENCE_COMPARE(c->in.event_responses_completed, <, reader.request)) + if(!_xcb_conn_wait(c, &cond, 0, 0)) + break; + + remove_reader(&c->in.event_readers, &reader); + pthread_cond_destroy(&cond); + _xcb_in_wake_up_next_reader(c); + pthread_mutex_unlock(&c->iolock); + return ret; +} + xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie) { uint64_t request; @@ -610,6 +649,8 @@ void _xcb_in_wake_up_next_reader(xcb_connection_t *c) int pthreadret; if(c->in.readers) pthreadret = pthread_cond_signal(c->in.readers->data); + else if(c->in.event_readers) + pthreadret = pthread_cond_signal(c->in.event_readers->data); else pthreadret = pthread_cond_signal(&c->in.event_cond); assert(pthreadret == 0); diff --git a/libxcb/src/xcbint.h b/libxcb/src/xcbint.h index 5950823f0..d1f742104 100644 --- a/libxcb/src/xcbint.h +++ b/libxcb/src/xcbint.h @@ -121,6 +121,7 @@ typedef struct _xcb_in { uint64_t request_expected; uint64_t request_read; + uint64_t event_responses_completed; uint64_t request_completed; struct reply_list *current_reply; struct reply_list **current_reply_tail; @@ -129,6 +130,7 @@ typedef struct _xcb_in { struct event_list *events; struct event_list **events_tail; struct reader_list *readers; + struct reader_list *event_readers; struct pending_reply *pending_replies; struct pending_reply **pending_replies_tail; -- cgit v1.2.3