Integrating XCB and libX11 event loops - hanging on select/poll inside Xt

1.2k views Asked by At

I am trying to integrate two bodies of code into the same process that each previously had independent event loops for their respective GUI toolkits - one of them using Xt, and the other using Qt5. The intention is just to be able to display Qt sub-windows, not to achieve full integration like the now defunct Qt/Motif integration extension.

I have been able to build a crude prototype running with the standard Qt event loop, with a native event filter that translates XCB events into XEvents (using XESetWireToEvent + its handler to translate from xEvents / X11 wire format). It then dispatches these XEvents directly to Xt with XtDispatchEvent(). At this point, I can run the program, and create both Xt/Motif widgets and Qt widgets in the same program, use menus, draw 2D graphics, and use both Qt & Motif widgets.

The problem I have, is that there is a lengthy delay when creating new Motif dialogs. I have tracked this down to _XtWaitForSomething() inside libXt, which ultimately comes down to what is apparently a select() or poll() on the X server's connection socket. This call to _XtWaitForSomething() occurs as a result of the layout management of the window occurring inside XtManageChild(). _XtWaitForSomething() appears to be checking if there are events pending in the event queue.

I have a number of questions:

  1. When using both XCB and libX11 calls in the same program (with XCB as event queue master) can I expect that calls from classic Xlib to also work properly - for example posting events to the XCB event queue via libX11 calls, or determining if there are any events pending in the XCB event queue via old libX11 calls?

  2. Why would XtManageChild() end up blocking on _XtWaitForSomething() inside libXt? It looks like it may be waiting for a geometry change event. Interestingly, Qt's platform layer is reading the XCB events in a separate thread, but then dispatching them in the main thread. I now wonder if Qt's XCB reader thread is eating the events before Xt gets a chance to check if event queue contains anything in _XtWaitForSomething(), leading to a deadlock. Is there any way to cause Qt's XCB event loop [or a general XCB event loop] to block while I make calls into Xt? I can't just modify Qt to have a condition variable in the XCB layer, since changing Qt is not an option.

 

#0  0x00000037b30e9a5d in poll () from /lib64/libc.so.6
#1  0x000000355f82d468 in _XtWaitForSomething () from /lib64/libXt.so.6
#2  0x00007ffff77b871f in _XmRootGeometryManager () from /lib64/libXm.so.2
#3  0x000000355f82569f in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#4  0x000000355f8257aa in XtMakeGeometryRequest () from /lib64/libXt.so.6

#5  0x00007ffff77b77e6 in geometry_manager () from /lib64/libXm.so.2
#6  0x000000355f8255f4 in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#6  0x000000355f8255f4 in _XtMakeGeometryRequest () from /lib64/libXt.so.6
#7  0x000000355f8257aa in XtMakeGeometryRequest () from /lib64/libXt.so.6
#8  0x00007ffff773852e in _XmMakeGeometryRequest () from /lib64/libXm.so.2
#9  0x00007ffff770ed51 in change_managed () from /lib64/libXm.so.2
#10 0x000000355f82a2e8 in XtRealizeWidget () from /lib64/libXt.so.6
#11 0x00007ffff771c8d6 in change_managed () from /lib64/libXm.so.2
#12 0x000000355f82c57d in ManageChildren () from /lib64/libXt.so.6
#13 0x000000355f82ca11 in XtManageChildren () from /lib64/libXt.so.6
#14 0x000000355f82cb18 in XtManageChild () from /lib64/libXt.so.6
...
  1. What exactly does event queue 'owner' status in XCB imply [XSetEventQueueOwner(..., XCBOwnsEventQueue)]. Does this imply that that XLib calls that harvest events will not actually 'take' any event from the head of the event queue?

  2. Are there any obviously blocking problems with the described approach? I already know that I will likely have to sort out timers (Xt function that handled these in event loop is no longer called), window parentage of Qt sub-windows to motif widgets, ...

Thanks.

1

There are 1 answers

0
Jan Wielemaker On

I'm seeing something similar. There is no Qt involved (only X11). In some cases there is an XtMakeGeometryRequest() call as an indirect call from processing a MapNotify event. Often this works fine. Sometimes there is a delay which seems to last exactly 5 seconds and which you can speedup by moving the window (using the mouse). This is related to timing. Not sure whether this is timing with the window manager or internal thread related timing in the application.

This problem didn't occur long time ago. It started with some Linux upgrade, but I'm afraid I can reproduce when.