Search code examples
x11xcb

XCB: How to "free" XID allocated by xcb_generate_id


(1) In XCB, we must manually allocate XID before some requests. For example,

xcb_window_t win = xcb_generate_id(conn);
xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, ...);

Then, what should we do to free (or unallocate) the XID? Is it enough to invoke xcb_destroy_window?

(2) How about in a case xcb_create_window fails? For example,

xcb_generic_cookie_t cookie = xcb_create_window_checked(conn, XCB_COPY_FROM_PARENT, win, ...);
if(xcb_request_check(conn, cookie)) ... // xcb_create_window failed.

In the example above, xcb_create_window failed. So, the XID win is allocated but not used. What should we do for win in this case?


Solution

  • Is it enough to invoke xcb_destroy_window?

    Yup. Sadly, I don't have any authoritative docs to link to, so I can just say "trust me".

    That's the simple answer for question 1. Answer 2... uhm, I guess it does not have a simple answer. So I guess you need "the full truth".

    When an X11 client connects to the X11 server, it is assigned a range of XIDs to use. These are the fields resource-id-base and resource-id-mask in the server response here: https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html#server_response

    Conceptually, these two fields describe something like "all XIDs from 0x100 to 0x200 are for you".

    xcb_generate_id() now simply returns the next entry from this range and marks it as used. So, after the first call and staying with the example above, "all XIDs from 0x101 to 0x200" are still available.

    This is quite a simple data structure and there is no way to return XIDs as "no longer used".

    So, what happens after all XIDs were used? For this, the XC-MISC extension exists: https://www.x.org/releases/X11R7.7/doc/xcmiscproto/xc-misc.html

    When it is out of XIDs, libxcb will send a XCMiscGetXIDRange request to get a "new" batch of XIDs and then starts handing out them.

    I write "new" in quotes since it is actually a sub-range of the original XID range: The X11 server knows which range it originally assigned this client. It knows which XIDs are in use. Thus, it can pick a free range and return it to the client.

    Thanks to this mechanism, libxcb does not have to track used XIDs in any way. Stuff just works automatically.