1 /* Copyright (C) 2003-2006 Jamey Sharp, Josh Triplett 2 * This file is licensed under the MIT license. See the file COPYING. */ 3 4 #ifdef HAVE_CONFIG_H 5 #include <config.h> 6 #endif 7 8 #include "Xlibint.h" 9 #include "locking.h" 10 #include "Xprivate.h" 11 #include "Xxcbint.h" 12 #include <xcb/xcbext.h> 13 14 #include <assert.h> 15 #ifdef HAVE_INTTYPES_H 16 #include <inttypes.h> 17 #endif 18 #include <stdio.h> 19 #include <stdint.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <limits.h> 23 #ifdef HAVE_SYS_SELECT_H 24 #include <sys/select.h> 25 #endif 26 27 #define xcb_fail_assert(_message, _var) do { \ 28 unsigned int _var = 1; \ 29 fprintf(stderr, "[xcb] Aborting, sorry about that.\n"); \ 30 assert(!_var); \ 31 } while (0) 32 33 #ifdef XTHREADS 34 #define throw_thread_fail_assert(_message, _var) do { \ 35 fprintf(stderr, "[xcb] " _message "\n"); \ 36 if (_Xglobal_lock) { \ 37 fprintf(stderr, "[xcb] You called XInitThreads, this is not your fault\n"); \ 38 } else { \ 39 fprintf(stderr, "[xcb] Most likely this is a multi-threaded client " \ 40 "and XInitThreads has not been called\n"); \ 41 } \ 42 xcb_fail_assert(_message, _var); \ 43 } while (0) 44 #else 45 #define throw_thread_fail_assert(_message, _var) do { \ 46 fprintf(stderr, "[xcb] " _message "\n"); \ 47 fprintf(stderr, "[xcb] The libX11 library was built without " \ 48 "multi-threading support\n"); \ 49 xcb_fail_assert(_message, _var); \ 50 } while (0) 51 #endif 52 53 /* XXX: It would probably be most useful if we stored the last-processed 54 * request, so we could find the offender from the message. */ 55 #define throw_extlib_fail_assert(_message, _var) do { \ 56 fprintf(stderr, "[xcb] " _message "\n"); \ 57 fprintf(stderr, "[xcb] This is most likely caused by a broken X " \ 58 "extension library\n"); \ 59 xcb_fail_assert(_message, _var); \ 60 } while (0) 61 62 static void return_socket(void *closure) 63 { 64 Display *dpy = closure; 65 InternalLockDisplay(dpy, /* don't skip user locks */ 0); 66 _XSend(dpy, NULL, 0); 67 dpy->bufmax = dpy->buffer; 68 UnlockDisplay(dpy); 69 } 70 71 static Bool require_socket(Display *dpy) 72 { 73 if(dpy->bufmax == dpy->buffer) 74 { 75 uint64_t sent; 76 int flags = 0; 77 /* if we don't own the event queue, we have to ask XCB 78 * to set our errors aside for us. */ 79 if(dpy->xcb->event_owner != XlibOwnsEventQueue) 80 flags = XCB_REQUEST_CHECKED; 81 if(!xcb_take_socket(dpy->xcb->connection, return_socket, dpy, 82 flags, &sent)) { 83 _XIOError(dpy); 84 return False; 85 } 86 dpy->xcb->last_flushed = sent; 87 X_DPY_SET_REQUEST(dpy, sent); 88 dpy->bufmax = dpy->xcb->real_bufmax; 89 } 90 return True; 91 } 92 93 /* Call internal connection callbacks for any fds that are currently 94 * ready to read. This function will not block unless one of the 95 * callbacks blocks. 96 * 97 * This code borrowed from _XWaitForReadable. Inverse call tree: 98 * _XRead 99 * _XWaitForWritable 100 * _XFlush 101 * _XSend 102 * _XEventsQueued 103 * _XReadEvents 104 * _XRead[0-9]+ 105 * _XAllocIDs 106 * _XReply 107 * _XEatData 108 * _XReadPad 109 */ 110 static Bool check_internal_connections(Display *dpy) 111 { 112 struct _XConnectionInfo *ilist; 113 fd_set r_mask; 114 struct timeval tv; 115 int result; 116 int highest_fd = -1; 117 118 if(dpy->flags & XlibDisplayProcConni || !dpy->im_fd_info) 119 return True; 120 121 FD_ZERO(&r_mask); 122 for(ilist = dpy->im_fd_info; ilist; ilist = ilist->next) 123 { 124 assert(ilist->fd >= 0); 125 FD_SET(ilist->fd, &r_mask); 126 if(ilist->fd > highest_fd) 127 highest_fd = ilist->fd; 128 } 129 assert(highest_fd >= 0); 130 131 tv.tv_sec = 0; 132 tv.tv_usec = 0; 133 result = select(highest_fd + 1, &r_mask, NULL, NULL, &tv); 134 135 if(result == -1) 136 { 137 if(errno != EINTR) { 138 _XIOError(dpy); 139 return False; 140 } 141 142 return True; 143 } 144 145 for(ilist = dpy->im_fd_info; result && ilist; ilist = ilist->next) 146 if(FD_ISSET(ilist->fd, &r_mask)) 147 { 148 _XProcessInternalConnection(dpy, ilist); 149 --result; 150 } 151 152 return True; 153 } 154 155 static PendingRequest *append_pending_request(Display *dpy, uint64_t sequence) 156 { 157 PendingRequest *node = malloc(sizeof(PendingRequest)); 158 assert(node); 159 node->next = NULL; 160 node->sequence = sequence; 161 node->reply_waiter = 0; 162 if(dpy->xcb->pending_requests_tail) 163 { 164 if (XLIB_SEQUENCE_COMPARE(dpy->xcb->pending_requests_tail->sequence, 165 >=, node->sequence)) 166 throw_thread_fail_assert("Unknown sequence number " 167 "while appending request", 168 xcb_xlib_unknown_seq_number); 169 if (dpy->xcb->pending_requests_tail->next != NULL) 170 throw_thread_fail_assert("Unknown request in queue " 171 "while appending request", 172 xcb_xlib_unknown_req_pending); 173 dpy->xcb->pending_requests_tail->next = node; 174 } 175 else 176 dpy->xcb->pending_requests = node; 177 dpy->xcb->pending_requests_tail = node; 178 return node; 179 } 180 181 static void dequeue_pending_request(Display *dpy, PendingRequest *req) 182 { 183 if (req != dpy->xcb->pending_requests) 184 throw_thread_fail_assert("Unknown request in queue while " 185 "dequeuing", 186 xcb_xlib_unknown_req_in_deq); 187 188 dpy->xcb->pending_requests = req->next; 189 if(!dpy->xcb->pending_requests) 190 { 191 if (req != dpy->xcb->pending_requests_tail) 192 throw_thread_fail_assert("Unknown request in queue " 193 "while dequeuing", 194 xcb_xlib_unknown_req_in_deq); 195 dpy->xcb->pending_requests_tail = NULL; 196 } 197 else if (XLIB_SEQUENCE_COMPARE(req->sequence, >=, 198 dpy->xcb->pending_requests->sequence)) 199 throw_thread_fail_assert("Unknown sequence number while " 200 "dequeuing request", 201 xcb_xlib_threads_sequence_lost); 202 203 free(req); 204 } 205 206 static int handle_error(Display *dpy, xError *err, Bool in_XReply) 207 { 208 _XExtension *ext; 209 int ret_code; 210 /* Oddly, Xlib only allows extensions to suppress errors when 211 * those errors were seen by _XReply. */ 212 if(in_XReply) 213 /* 214 * we better see if there is an extension who may 215 * want to suppress the error. 216 */ 217 for(ext = dpy->ext_procs; ext; ext = ext->next) 218 if(ext->error && (*ext->error)(dpy, err, &ext->codes, &ret_code)) 219 return ret_code; 220 _XError(dpy, err); 221 return 0; 222 } 223 224 /* Widen a 32-bit sequence number into a 64bit (uint64_t) sequence number. 225 * Treating the comparison as a 1 and shifting it avoids a conditional branch. 226 */ 227 static void widen(uint64_t *wide, unsigned int narrow) 228 { 229 uint64_t new = (*wide & ~((uint64_t)0xFFFFFFFFUL)) | narrow; 230 /* If just copying the upper dword of *wide makes the number 231 * go down by more than 2^31, then it means that the lower 232 * dword has wrapped (or we have skipped 2^31 requests, which 233 * is hopefully improbable), so we add a carry. */ 234 uint64_t wraps = new + (1UL << 31) < *wide; 235 *wide = new + (wraps << 32); 236 } 237 238 /* Thread-safety rules: 239 * 240 * At most one thread can be reading from XCB's event queue at a time. 241 * If you are not the current event-reading thread and you need to find 242 * out if an event is available, you must wait. 243 * 244 * The same rule applies for reading replies. 245 * 246 * A single thread cannot be both the the event-reading and the 247 * reply-reading thread at the same time. 248 * 249 * We always look at both the current event and the first pending reply 250 * to decide which to process next. 251 * 252 * We always process all responses in sequence-number order, which may 253 * mean waiting for another thread (either the event_waiter or the 254 * reply_waiter) to handle an earlier response before we can process or 255 * return a later one. If so, we wait on the corresponding condition 256 * variable for that thread to process the response and wake us up. 257 */ 258 259 static xcb_generic_reply_t *poll_for_event(Display *dpy, Bool queued_only) 260 { 261 /* Make sure the Display's sequence numbers are valid */ 262 if (!require_socket(dpy)) 263 return NULL; 264 265 /* Precondition: This thread can safely get events from XCB. */ 266 assert(dpy->xcb->event_owner == XlibOwnsEventQueue && !dpy->xcb->event_waiter); 267 268 if(!dpy->xcb->next_event) { 269 if(queued_only) 270 dpy->xcb->next_event = xcb_poll_for_queued_event(dpy->xcb->connection); 271 else 272 dpy->xcb->next_event = xcb_poll_for_event(dpy->xcb->connection); 273 } 274 275 if(dpy->xcb->next_event) 276 { 277 PendingRequest *req = dpy->xcb->pending_requests; 278 xcb_generic_event_t *event = dpy->xcb->next_event; 279 uint64_t event_sequence = X_DPY_GET_LAST_REQUEST_READ(dpy); 280 widen(&event_sequence, event->full_sequence); 281 if(!req || XLIB_SEQUENCE_COMPARE(event_sequence, <, req->sequence) 282 || (event->response_type != X_Error && event_sequence == req->sequence)) 283 { 284 uint64_t request = X_DPY_GET_REQUEST(dpy); 285 if (XLIB_SEQUENCE_COMPARE(event_sequence, >, request)) 286 { 287 throw_thread_fail_assert("Unknown sequence " 288 "number while " 289 "processing queue", 290 xcb_xlib_threads_sequence_lost); 291 } 292 X_DPY_SET_LAST_REQUEST_READ(dpy, event_sequence); 293 dpy->xcb->next_event = NULL; 294 return (xcb_generic_reply_t *) event; 295 } 296 } 297 return NULL; 298 } 299 300 static xcb_generic_reply_t *poll_for_response(Display *dpy) 301 { 302 void *response; 303 xcb_generic_reply_t *event; 304 PendingRequest *req; 305 306 while(1) 307 { 308 xcb_generic_error_t *error = NULL; 309 uint64_t request; 310 Bool poll_queued_only = dpy->xcb->next_response != NULL; 311 312 /* Step 1: is there an event in our queue before the next 313 * reply/error? Return that first. 314 * 315 * If we don't have a reply/error saved from an earlier 316 * invocation we check incoming events too, otherwise only 317 * the ones already queued. 318 */ 319 response = poll_for_event(dpy, poll_queued_only); 320 if(response) 321 break; 322 323 /* Step 2: 324 * Response is NULL, i.e. we have no events. 325 * If we are not waiting for a reply or some other thread 326 * had dibs on the next reply, exit. 327 */ 328 req = dpy->xcb->pending_requests; 329 if(!req || req->reply_waiter) 330 break; 331 332 /* Step 3: 333 * We have some response (error or reply) related to req 334 * saved from an earlier invocation of this function. Let's 335 * use that one. 336 */ 337 if(dpy->xcb->next_response) 338 { 339 if (((xcb_generic_reply_t*)dpy->xcb->next_response)->response_type == X_Error) 340 { 341 error = dpy->xcb->next_response; 342 response = NULL; 343 } 344 else 345 { 346 response = dpy->xcb->next_response; 347 error = NULL; 348 } 349 dpy->xcb->next_response = NULL; 350 } 351 else 352 { 353 /* Step 4: pull down the next response from the wire. This 354 * should be the 99% case. 355 * xcb_poll_for_reply64() may also pull down events that 356 * happened before the reply. 357 */ 358 if(!xcb_poll_for_reply64(dpy->xcb->connection, req->sequence, 359 &response, &error)) { 360 /* if there is no reply/error, xcb_poll_for_reply64 361 * may have read events. Return that. */ 362 response = poll_for_event(dpy, True); 363 break; 364 } 365 366 /* Step 5: we have a new response, but we may also have some 367 * events that happened before that response. Return those 368 * first and save our reply/error for the next invocation. 369 */ 370 event = poll_for_event(dpy, True); 371 if(event) 372 { 373 dpy->xcb->next_response = error ? error : response; 374 response = event; 375 break; 376 } 377 } 378 379 /* Step 6: actually handle the reply/error now... */ 380 request = X_DPY_GET_REQUEST(dpy); 381 if(XLIB_SEQUENCE_COMPARE(req->sequence, >, request)) 382 { 383 throw_thread_fail_assert("Unknown sequence number " 384 "while awaiting reply", 385 xcb_xlib_threads_sequence_lost); 386 } 387 X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence); 388 if(response) 389 break; 390 dequeue_pending_request(dpy, req); 391 if(error) 392 return (xcb_generic_reply_t *) error; 393 } 394 return response; 395 } 396 397 static void handle_response(Display *dpy, xcb_generic_reply_t *response, Bool in_XReply) 398 { 399 _XAsyncHandler *async, *next; 400 switch(response->response_type) 401 { 402 case X_Reply: 403 for(async = dpy->async_handlers; async; async = next) 404 { 405 next = async->next; 406 if(async->handler(dpy, (xReply *) response, (char *) response, sizeof(xReply) + (response->length << 2), async->data)) 407 break; 408 } 409 break; 410 411 case X_Error: 412 handle_error(dpy, (xError *) response, in_XReply); 413 break; 414 415 default: /* event */ 416 /* GenericEvents may be > 32 bytes. In this case, the 417 * event struct is trailed by the additional bytes. the 418 * xcb_generic_event_t struct uses 4 bytes for internal 419 * numbering, so we need to shift the trailing data to 420 * be after the first 32 bytes. */ 421 if(response->response_type == GenericEvent && ((xcb_ge_event_t *) response)->length) 422 { 423 xcb_ge_event_t *event = (xcb_ge_event_t *) response; 424 memmove(&event->full_sequence, &event[1], event->length * 4); 425 } 426 _XEnq(dpy, (xEvent *) response); 427 break; 428 } 429 free(response); 430 } 431 432 int _XEventsQueued(Display *dpy, int mode) 433 { 434 xcb_generic_reply_t *response; 435 if(dpy->flags & XlibDisplayIOError) 436 return 0; 437 if(dpy->xcb->event_owner != XlibOwnsEventQueue) 438 return 0; 439 440 if(mode == QueuedAfterFlush) 441 _XSend(dpy, NULL, 0); 442 else if (!check_internal_connections(dpy)) 443 return 0; 444 445 /* If another thread is blocked waiting for events, then we must 446 * let that thread pick up the next event. Since it blocked, we 447 * can reasonably claim there are no new events right now. */ 448 if(!dpy->xcb->event_waiter) 449 { 450 while((response = poll_for_response(dpy))) 451 handle_response(dpy, response, False); 452 if(xcb_connection_has_error(dpy->xcb->connection)) { 453 _XIOError(dpy); 454 return 0; 455 } 456 } 457 return dpy->qlen; 458 } 459 460 /* _XReadEvents - Flush the output queue, 461 * then read as many events as possible (but at least 1) and enqueue them 462 */ 463 void _XReadEvents(Display *dpy) 464 { 465 xcb_generic_reply_t *response; 466 unsigned long serial; 467 468 if(dpy->flags & XlibDisplayIOError) 469 return; 470 _XSend(dpy, NULL, 0); 471 if(dpy->xcb->event_owner != XlibOwnsEventQueue) 472 return; 473 if (!check_internal_connections(dpy)) 474 return; 475 476 serial = dpy->next_event_serial_num; 477 while(serial == dpy->next_event_serial_num || dpy->qlen == 0) 478 { 479 if(dpy->xcb->event_waiter) 480 { 481 ConditionWait(dpy, dpy->xcb->event_notify); 482 /* Maybe the other thread got us an event. */ 483 continue; 484 } 485 486 if(!dpy->xcb->next_event) 487 { 488 xcb_generic_event_t *event; 489 dpy->xcb->event_waiter = 1; 490 UnlockDisplay(dpy); 491 event = xcb_wait_for_event(dpy->xcb->connection); 492 /* It appears that classic Xlib respected user 493 * locks when waking up after waiting for 494 * events. However, if this thread did not have 495 * any user locks, and another thread takes a 496 * user lock and tries to read events, then we'd 497 * deadlock. So we'll choose to let the thread 498 * that got in first consume events, despite the 499 * later thread's user locks. */ 500 InternalLockDisplay(dpy, /* ignore user locks */ 1); 501 dpy->xcb->event_waiter = 0; 502 ConditionBroadcast(dpy, dpy->xcb->event_notify); 503 if(!event) 504 { 505 _XIOError(dpy); 506 return; 507 } 508 dpy->xcb->next_event = event; 509 } 510 511 /* We've established most of the conditions for 512 * poll_for_response to return non-NULL. The exceptions 513 * are connection shutdown, and finding that another 514 * thread is waiting for the next reply we'd like to 515 * process. */ 516 517 response = poll_for_response(dpy); 518 if(response) 519 handle_response(dpy, response, False); 520 else if(dpy->xcb->pending_requests->reply_waiter) 521 { /* need braces around ConditionWait */ 522 ConditionWait(dpy, dpy->xcb->reply_notify); 523 } 524 else 525 { 526 _XIOError(dpy); 527 return; 528 } 529 } 530 531 /* The preceding loop established that there is no 532 * event_waiter--unless we just called ConditionWait because of 533 * a reply_waiter, in which case another thread may have become 534 * the event_waiter while we slept unlocked. */ 535 if(!dpy->xcb->event_waiter) 536 while((response = poll_for_response(dpy))) 537 handle_response(dpy, response, False); 538 if(xcb_connection_has_error(dpy->xcb->connection)) 539 _XIOError(dpy); 540 } 541 542 /* 543 * _XSend - Flush the buffer and send the client data. 32 bit word aligned 544 * transmission is used, if size is not 0 mod 4, extra bytes are transmitted. 545 * 546 * Note that the connection must not be read from once the data currently 547 * in the buffer has been written. 548 */ 549 void _XSend(Display *dpy, const char *data, long size) 550 { 551 static const xReq dummy_request; 552 static char const pad[3]; 553 struct iovec vec[3]; 554 uint64_t requests; 555 uint64_t dpy_request; 556 _XExtension *ext; 557 xcb_connection_t *c = dpy->xcb->connection; 558 if(dpy->flags & XlibDisplayIOError) 559 return; 560 561 if(dpy->bufptr == dpy->buffer && !size) 562 return; 563 564 /* append_pending_request does not alter the dpy request number 565 * therefore we can get it outside of the loop and the if 566 */ 567 dpy_request = X_DPY_GET_REQUEST(dpy); 568 /* iff we asked XCB to set aside errors, we must pick those up 569 * eventually. iff there are async handlers, we may have just 570 * issued requests that will generate replies. in either case, 571 * we need to remember to check later. */ 572 if(dpy->xcb->event_owner != XlibOwnsEventQueue || dpy->async_handlers) 573 { 574 uint64_t sequence; 575 for(sequence = dpy->xcb->last_flushed + 1; sequence <= dpy_request; ++sequence) 576 append_pending_request(dpy, sequence); 577 } 578 requests = dpy_request - dpy->xcb->last_flushed; 579 dpy->xcb->last_flushed = dpy_request; 580 581 vec[0].iov_base = dpy->buffer; 582 vec[0].iov_len = dpy->bufptr - dpy->buffer; 583 vec[1].iov_base = (char *)data; 584 vec[1].iov_len = size; 585 vec[2].iov_base = (char *)pad; 586 vec[2].iov_len = -size & 3; 587 588 for(ext = dpy->flushes; ext; ext = ext->next_flush) 589 { 590 int i; 591 for(i = 0; i < 3; ++i) 592 if(vec[i].iov_len) 593 ext->before_flush(dpy, &ext->codes, vec[i].iov_base, vec[i].iov_len); 594 } 595 596 if(xcb_writev(c, vec, 3, requests) < 0) { 597 _XIOError(dpy); 598 return; 599 } 600 dpy->bufptr = dpy->buffer; 601 dpy->last_req = (char *) &dummy_request; 602 603 if (!check_internal_connections(dpy)) 604 return; 605 606 _XSetSeqSyncFunction(dpy); 607 } 608 609 /* 610 * _XFlush - Flush the X request buffer. If the buffer is empty, no 611 * action is taken. 612 */ 613 void _XFlush(Display *dpy) 614 { 615 if (!require_socket(dpy)) 616 return; 617 618 _XSend(dpy, NULL, 0); 619 620 _XEventsQueued(dpy, QueuedAfterReading); 621 } 622 623 static const XID inval_id = ~0UL; 624 625 void _XIDHandler(Display *dpy) 626 { 627 if (dpy->xcb->next_xid == inval_id) 628 _XAllocIDs(dpy, &dpy->xcb->next_xid, 1); 629 } 630 631 /* _XAllocID - resource ID allocation routine. */ 632 XID _XAllocID(Display *dpy) 633 { 634 XID ret = dpy->xcb->next_xid; 635 assert (ret != inval_id); 636 dpy->xcb->next_xid = inval_id; 637 _XSetPrivSyncFunction(dpy); 638 return ret; 639 } 640 641 /* _XAllocIDs - multiple resource ID allocation routine. */ 642 void _XAllocIDs(Display *dpy, XID *ids, int count) 643 { 644 int i; 645 #ifdef XTHREADS 646 if (dpy->lock) 647 (*dpy->lock->user_lock_display)(dpy); 648 UnlockDisplay(dpy); 649 #endif 650 for (i = 0; i < count; i++) 651 ids[i] = xcb_generate_id(dpy->xcb->connection); 652 #ifdef XTHREADS 653 InternalLockDisplay(dpy, /* don't skip user locks */ 0); 654 if (dpy->lock) 655 (*dpy->lock->user_unlock_display)(dpy); 656 #endif 657 } 658 659 static void _XFreeReplyData(Display *dpy, Bool force) 660 { 661 if(!force && dpy->xcb->reply_consumed < dpy->xcb->reply_length) 662 return; 663 free(dpy->xcb->reply_data); 664 dpy->xcb->reply_data = NULL; 665 } 666 667 /* 668 * _XReply - Wait for a reply packet and copy its contents into the 669 * specified rep. 670 * extra: number of 32-bit words expected after the reply 671 * discard: should I discard data following "extra" words? 672 */ 673 Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard) 674 { 675 xcb_generic_error_t *error; 676 xcb_connection_t *c = dpy->xcb->connection; 677 char *reply; 678 PendingRequest *current; 679 uint64_t dpy_request; 680 681 if (dpy->xcb->reply_data) 682 throw_extlib_fail_assert("Extra reply data still left in queue", 683 xcb_xlib_extra_reply_data_left); 684 685 if(dpy->flags & XlibDisplayIOError) 686 return 0; 687 688 _XSend(dpy, NULL, 0); 689 dpy_request = X_DPY_GET_REQUEST(dpy); 690 if(dpy->xcb->pending_requests_tail 691 && dpy->xcb->pending_requests_tail->sequence == dpy_request) 692 current = dpy->xcb->pending_requests_tail; 693 else 694 current = append_pending_request(dpy, dpy_request); 695 /* Don't let any other thread get this reply. */ 696 current->reply_waiter = 1; 697 698 while(1) 699 { 700 PendingRequest *req = dpy->xcb->pending_requests; 701 xcb_generic_reply_t *response; 702 703 if(req != current && req->reply_waiter) 704 { 705 ConditionWait(dpy, dpy->xcb->reply_notify); 706 /* Another thread got this reply. */ 707 continue; 708 } 709 req->reply_waiter = 1; 710 UnlockDisplay(dpy); 711 response = xcb_wait_for_reply64(c, req->sequence, &error); 712 /* Any user locks on another thread must have been taken 713 * while we slept in xcb_wait_for_reply64. Classic Xlib 714 * ignored those user locks in this case, so we do too. */ 715 InternalLockDisplay(dpy, /* ignore user locks */ 1); 716 717 /* We have the response we're looking for. Now, before 718 * letting anyone else process this sequence number, we 719 * need to process any events that should have come 720 * earlier. */ 721 722 if(dpy->xcb->event_owner == XlibOwnsEventQueue) 723 { 724 xcb_generic_reply_t *event; 725 726 /* Assume event queue is empty if another thread is blocking 727 * waiting for event. */ 728 if(!dpy->xcb->event_waiter) 729 { 730 while((event = poll_for_response(dpy))) 731 handle_response(dpy, event, True); 732 } 733 } 734 735 req->reply_waiter = 0; 736 ConditionBroadcast(dpy, dpy->xcb->reply_notify); 737 dpy_request = X_DPY_GET_REQUEST(dpy); 738 if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy_request)) { 739 throw_thread_fail_assert("Unknown sequence number " 740 "while processing reply", 741 xcb_xlib_threads_sequence_lost); 742 } 743 X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence); 744 if(!response) 745 dequeue_pending_request(dpy, req); 746 747 if(req == current) 748 { 749 reply = (char *) response; 750 break; 751 } 752 753 if(error) 754 handle_response(dpy, (xcb_generic_reply_t *) error, True); 755 else if(response) 756 handle_response(dpy, response, True); 757 } 758 if (!check_internal_connections(dpy)) 759 return 0; 760 761 if(dpy->xcb->next_event && dpy->xcb->next_event->response_type == X_Error) 762 { 763 xcb_generic_event_t *event = dpy->xcb->next_event; 764 uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy); 765 uint64_t event_sequence = last_request_read; 766 widen(&event_sequence, event->full_sequence); 767 if(event_sequence == last_request_read) 768 { 769 error = (xcb_generic_error_t *) event; 770 dpy->xcb->next_event = NULL; 771 } 772 } 773 774 if(error) 775 { 776 int ret_code; 777 778 /* Xlib is evil and assumes that even errors will be 779 * copied into rep. */ 780 memcpy(rep, error, 32); 781 782 /* do not die on "no such font", "can't allocate", 783 "can't grab" failures */ 784 switch(error->error_code) 785 { 786 case BadName: 787 switch(error->major_code) 788 { 789 case X_LookupColor: 790 case X_AllocNamedColor: 791 free(error); 792 return 0; 793 } 794 break; 795 case BadFont: 796 if(error->major_code == X_QueryFont) { 797 free(error); 798 return 0; 799 } 800 break; 801 case BadAlloc: 802 case BadAccess: 803 free(error); 804 return 0; 805 } 806 807 ret_code = handle_error(dpy, (xError *) error, True); 808 free(error); 809 return ret_code; 810 } 811 812 /* it's not an error, but we don't have a reply, so it's an I/O 813 * error. */ 814 if(!reply) { 815 _XIOError(dpy); 816 return 0; 817 } 818 819 /* there's no error and we have a reply. */ 820 dpy->xcb->reply_data = reply; 821 dpy->xcb->reply_consumed = sizeof(xReply) + (extra * 4); 822 dpy->xcb->reply_length = sizeof(xReply); 823 if(dpy->xcb->reply_data[0] == 1) 824 dpy->xcb->reply_length += (((xcb_generic_reply_t *) dpy->xcb->reply_data)->length * 4); 825 826 /* error: Xlib asks too much. give them what we can anyway. */ 827 if(dpy->xcb->reply_length < dpy->xcb->reply_consumed) 828 dpy->xcb->reply_consumed = dpy->xcb->reply_length; 829 830 memcpy(rep, dpy->xcb->reply_data, dpy->xcb->reply_consumed); 831 _XFreeReplyData(dpy, discard); 832 return 1; 833 } 834 835 int _XRead(Display *dpy, char *data, long size) 836 { 837 assert(size >= 0); 838 if(size == 0) 839 return 0; 840 if(dpy->xcb->reply_data == NULL || 841 dpy->xcb->reply_consumed + size > dpy->xcb->reply_length) 842 throw_extlib_fail_assert("Too much data requested from _XRead", 843 xcb_xlib_too_much_data_requested); 844 memcpy(data, dpy->xcb->reply_data + dpy->xcb->reply_consumed, size); 845 dpy->xcb->reply_consumed += size; 846 _XFreeReplyData(dpy, False); 847 return 0; 848 } 849 850 /* 851 * _XReadPad - Read bytes from the socket taking into account incomplete 852 * reads. If the number of bytes is not 0 mod 4, read additional pad 853 * bytes. 854 */ 855 void _XReadPad(Display *dpy, char *data, long size) 856 { 857 _XRead(dpy, data, size); 858 dpy->xcb->reply_consumed += -size & 3; 859 _XFreeReplyData(dpy, False); 860 } 861 862 /* Read and discard "n" 8-bit bytes of data */ 863 void _XEatData(Display *dpy, unsigned long n) 864 { 865 dpy->xcb->reply_consumed += n; 866 _XFreeReplyData(dpy, False); 867 } 868 869 /* 870 * Read and discard "n" 32-bit words of data 871 * Matches the units of the length field in X protocol replies, and provides 872 * a single implementation of overflow checking to avoid having to replicate 873 * those checks in every caller. 874 */ 875 void _XEatDataWords(Display *dpy, unsigned long n) 876 { 877 if (n < ((INT_MAX - dpy->xcb->reply_consumed) >> 2)) 878 dpy->xcb->reply_consumed += (n << 2); 879 else 880 /* Overflow would happen, so just eat the rest of the reply */ 881 dpy->xcb->reply_consumed = dpy->xcb->reply_length; 882 _XFreeReplyData(dpy, False); 883 } 884 885 unsigned long 886 _XNextRequest(Display *dpy) 887 { 888 /* This will update dpy->request. The assumption is that the next thing 889 * that the application will do is make a request so there's little 890 * overhead. 891 */ 892 require_socket(dpy); 893 return NextRequest(dpy); 894 } 895