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;
}
예제 #2
0
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;
    }