[Xcb] Questions about the X protocol and the XCB implementation

Jochen Keil jochen.keil at gmail.com
Thu Jan 30 01:21:18 PST 2014


On 29.01.2014 22:43, Uli Schlachter wrote:
> On 29.01.2014 22:18, Jochen Keil wrote:
>> Thanks for your answer. The main problem is, that I cannot easily reuse
>> the {xcb_,}send_* functions, because each calls another subsequently.
> Uhm, another what?
Oh, sorry, my phrasing slipped here and I didn't notice it while proof
reading. I meant to say that the {xcb_,}send_* functions call each
other, which limits their reuse somewhat. (xcb_send_request calls
send_request, send_request calls _xcb_out_send which calls

>> Basically, here's what I think I could do. First, create a request
>> without the payload (because it's in a container). Then copy it into the
>> queue. After that, copy the payload directly into the queue and
>> (possibly) trigger the actual send.
> That doesn't sound thread safe, but I'll just assume that this is not
an issue
> for you.

I thought I could put my code at the same place like send_request()
where it would be guarded by the lock (c->iolock) from xcb_send_request.
Then I could go wild on the queue without concerns about thread safety.

>> That would at least save me the transformation of the container to an
>> array and I think it could be easier to implement (However, I still
>> would have to duplicate some code which is something I'm not too happy
>> about).
> I am not sure what you mean exactly. The (only) public function that
you might
> want to use would be xcb_send_request() (unless you want to go through the
> uglyness of xcb_take_socket() and xcb_writev() which you might
actually want to
> do...).

Hm, I figured I could save me one copy by copying the values directly to
the queue. I'll explain it with an example. At the moment, if you have
a map with key/value pairs, you would have to copy all the values to
a c array, then pass the array and its length to a xcb_<request>
function. Then, within that request, the array gets copied again, this
time to the queue. I'm looking to avoid that first copy. However, as
I explained above, xcb_send_request, etc. are not quite reusable for me
because of the subsequent calls. Hence, I'd have to duplicate most of
the code (at least in xcb_send_request).

> For xcb_send_request(), you'd have to set up an array of iovecs anyway.
> If each of those is quite small and only contains some bytes, the
result would
> again be inefficient and just copying things into a block would be faster.
> I guess that only xcb_put_image() actually makes sense for something
like this.
> At least I can't think right now of a (common) request that could need
to send
> lots of data.

These points are my biggest concern and I think I will refrain from
implementing this because of the meager potential performance gain. As
you pointed out, almost all request never carry enough data to make
performance an issue. The only potential winner is PutImage, but that
should be used sparingly either (and I think it would be very unusual to
keep multiple images in a container, opposed to only keeping pointers to

Thanks for your exhausting answer, it was certainly helpful for my

All the best,

> Cheers,
> Uli
>>> On Tue, Jan 28, 2014 at 3:04 PM, Jochen Keil <jochen.keil at gmail.com>
>>>> Hello,
>>>> currently I'm trying to understand the X protocol and the XCB
>>>> implementation better. My first question about the X protocol would be
>>>> if there is something like a picture or so which describes the
>>>> (byte-wise) layout of a request/event/etc. packet.
>>>> Maybe similar to what exists for the TCP/IP packets. Or is this
>>>> a misconception of mine?
>>>> Secondly I've looked a bit at the XCB implementation, starting from
>>>> a generated request (xcb_change_property) to the stubs. If I understood
>>>> it correctly, the request function calls xcb_send_request ->
>>>> send_request -> _xcb_out_send -> _xcb_conn_wait -> write_vec.
>>>> write_vec finally send()s the data over the socket.
>>>> Now, if I have a (high-level) container like a C++ map, I would have to
>>>> transform (copy) the values to an array first, which then gets copied
>>>> again by memcpy in send_request().
>>>> I figured, that it would be good if the values from the container could
>>>> be written directly to the socket. E.g.:
>>>> for (k, v in map) { send(c-fd, &v, sizeof(v)); }
>>>> Now I'd like to know if this makes sense at all and if I could
>>>> this easily by (re-)using the existing implementation.
>>>> My biggest problem is to understand what xcb_send_request does. Could
>>>> I just send a request "head" (e.g. for change_property: mode, window,
>>>> property,
>>>> type, format) followed by the data in separate send() calls?
>>>> I hope I expressed my ideas clearly enough. Please ask, if I should go
>>>> more into detail about something. I also appreciate any critique!
>>>> Thank you,
>>>> Jochen
>>>> _______________________________________________
>>>> Xcb mailing list
>>>> Xcb at lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/xcb
>> _______________________________________________
>> Xcb mailing list
>> Xcb at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/xcb

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/xcb/attachments/20140130/d4deedb0/attachment-0001.pgp>

More information about the Xcb mailing list