static lazyreply *get_lazyreply(XCBConnection *c, XCBExtension *ext) { static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; static int next_global_id; lazyreply *data; pthread_mutex_lock(&global_lock); if(!ext->global_id) ext->global_id = ++next_global_id; pthread_mutex_unlock(&global_lock); data = _xcb_map_get(c->ext.extensions, ext->global_id); if(!data) { /* cache miss: query the server */ data = malloc(sizeof(lazyreply)); if(!data) return 0; data->tag = LAZY_COOKIE; data->value.cookie = XCBQueryExtension(c, strlen(ext->name), ext->name); _xcb_map_put(c->ext.extensions, ext->global_id, data); } return data; }
static int read_packet(xcb_connection_t *c) { xcb_generic_reply_t genrep; int length = 32; int eventlength = 0; /* length after first 32 bytes for GenericEvents */ void *buf; pending_reply *pend = 0; struct event_list *event; /* Wait for there to be enough data for us to read a whole packet */ if(c->in.queue_len < length) return 0; /* Get the response type, length, and sequence number. */ memcpy(&genrep, c->in.queue, sizeof(genrep)); /* Compute 32-bit sequence number of this packet. */ if((genrep.response_type & 0x7f) != XCB_KEYMAP_NOTIFY) { uint64_t lastread = c->in.request_read; c->in.request_read = (lastread & UINT64_C(0xffffffffffff0000)) | genrep.sequence; if(XCB_SEQUENCE_COMPARE(c->in.request_read, <, lastread)) c->in.request_read += 0x10000; if(XCB_SEQUENCE_COMPARE(c->in.request_read, >, c->in.request_expected)) c->in.request_expected = c->in.request_read; if(c->in.request_read != lastread) { if(c->in.current_reply) { _xcb_map_put(c->in.replies, lastread, c->in.current_reply); c->in.current_reply = 0; c->in.current_reply_tail = &c->in.current_reply; } c->in.request_completed = c->in.request_read - 1; } while(c->in.pending_replies && c->in.pending_replies->workaround != WORKAROUND_EXTERNAL_SOCKET_OWNER && XCB_SEQUENCE_COMPARE (c->in.pending_replies->last_request, <=, c->in.request_completed)) { pending_reply *oldpend = c->in.pending_replies; c->in.pending_replies = oldpend->next; if(!oldpend->next) c->in.pending_replies_tail = &c->in.pending_replies; free(oldpend); } if(genrep.response_type == XCB_ERROR) c->in.request_completed = c->in.request_read; }