6

2 つのコード本体を、以前はそれぞれの GUI ツールキット用に独立したイベント ループを持っていた同じプロセスに統合しようとしています。1 つは Xt を使用し、もう 1 つは Qt5 を使用しています。その意図は、Qt サブウィンドウを表示できるようにすることであり、現在は機能していない Qt/Motif 統合拡張機能のような完全な統合を実現することではありません。

XCB イベントを XEvent に変換するネイティブ イベント フィルターを使用して、標準の Qt イベント ループで動作する粗いプロトタイプを作成できました (XESetWireToEvent + そのハンドラーを使用して xEvents / X11 ワイヤー フォーマットから変換します)。次に、XtDispatchEvent() を使用して、これらの XEvent を Xt に直接ディスパッチします。この時点で、プログラムを実行し、同じプログラムで Xt/Motif ウィジェットと Qt ウィジェットの両方を作成し、メニューを使用し、2D グラフィックスを描画し、Qt と Motif ウィジェットの両方を使用できます。

私が抱えている問題は、新しい Motif ダイアログを作成するときに長い遅延があることです。これを libXt 内の _XtWaitForSomething() まで追跡しました。最終的には、明らかに X サーバーの接続ソケット上の select() または poll() に行き着きます。_XtWaitForSomething() へのこの呼び出しは、XtManageChild() 内で発生するウィンドウのレイアウト管理の結果として発生します。_XtWaitForSomething() は、イベント キューに保留中のイベントがあるかどうかをチェックしているようです。

いくつか質問があります:

  1. XCB と libX11 の両方の呼び出しを同じプログラム (イベント キュー マスターとして XCB を使用) で使用する場合、従来の Xlib からの呼び出しも適切に機能することを期待できますか? たとえば、libX11 呼び出しを介して XCB イベント キューにイベントをポストしたり、古い libX11 呼び出しを介して XCB イベント キューで保留中のイベントはありますか?

  2. XtManageChild() が libXt 内の _XtWaitForSomething() でブロックされるのはなぜですか? ジオメトリ変更イベントを待っている可能性があります。興味深いことに、Qt のプラットフォーム レイヤーは XCB イベントを別のスレッドで読み取りますが、メイン スレッドでディスパッチします。Xt が _XtWaitForSomething() にイベント キューに何かが含まれているかどうかを確認する機会を得る前に、Qt の XCB リーダー スレッドがイベントを食べて、デッドロックにつながるのではないかと思います。Xt を呼び出している間に Qt の XCB イベント ループ [または一般的な XCB イベント ループ] をブロックさせる方法はありますか? Qt の変更はオプションではないため、Qt を変更して XCB レイヤーに条件変数を含めることはできません。

 

#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. XCB のイベント キューの「所有者」ステータスは、[XSetEventQueueOwner(..., XCBOwnsEventQueue)] を意味します。これは、イベントを収集する XLib 呼び出しが実際にはイベント キューの先頭からイベントを「取得」しないことを意味しますか?

  2. 説明されているアプローチで明らかにブロックする問題はありますか? タイマー (イベント ループでこれらを処理する Xt 関数は呼び出されなくなりました)、モチーフ ウィジェットへの Qt サブウィンドウのウィンドウ親子関係を整理する必要がある可能性が高いことは既にわかっています。

ありがとう。

4

1 に答える 1

0

私は似たようなものを見ています。関与する Qt はありません (X11 のみ)。場合によっては、MapNotifyイベント処理からの間接呼び出しとして XtMakeGeometryRequest() 呼び出しがあります。多くの場合、これでうまくいきます。時々、正確に 5 秒続くように見える遅延があり、(マウスを使用して) ウィンドウを移動することで速度を上げることができます。これにはタイミングが関係しています。これがウィンドウ マネージャのタイミングなのか、アプリケーションの内部スレッド関連のタイミングなのかは不明です。

この問題は、長い間発生していませんでした。Linux のアップグレードで始まったのですが、いつ再現できるか心配です。

于 2022-02-16T13:51:03.803 に答える