2

CYBOI の一部のコードを Xlib から XCB に移行しています。

CYBOI は、serial_port、ターミナル、ソケット、x_window_system などのさまざまな通信チャネルにいくつかのスレッドを使用します。ただし、これらのスレッドはシグナル/イベント/データの検出にのみ使用されます。アドレス空間のマルチスレッド競合を避けるために、実際の送受信はメインスレッドで行われます。

x_window_system チャネルについては、以前にスレッドでイベントを検出しました。

int n = XEventsQueued(display, QueuedAfterReading);

イベントの検出時に、「割り込みフラグ」が設定されました。その後、メインスレッドは以下を使用して実際のイベントを読み取っていました。

XNextEvent(display, &event);

使用可能なイベントがなくなると、メイン スレッドはイベントの受信を停止し、x_window_system チャネル スレッドは XEventsQueued を再びリッスンし始めました。

現在、コードを XC Binding (XCB) に移行しています。イベントの読み取りに適したブロッキング関数「xcb_wait_for_event」があります。私が見逃しているのは、保留中のイベントがある場合、実際にキューからイベントを返したり削除したりせずに、「先を覗く」機能です。

私は数時間ウェブを読んでいましたが、そのような機能を見つけることができません. 「xcb_poll_for_event」は役に立ちません。イベント検出は独自のスレッドで実行されるため、ブロッキングは問題ありません。3 番目の入力関数としての「xcb_request_check」は、私が望むものではないようです。

誰か助けてくれませんか?

ありがとう、クリスチャン

4

2 に答える 2

1

まず、返信してくれた Julien に感謝します。

XCB 1.9 のソースを調べたところ、「xcb_poll_for_queued_event」関数が必要なものではないことがわかりました。

関数「xcb_poll_for_event」と「xcb_poll_for_queued_event」はどちらも「poll_for_next_event」を呼び出します。関数「poll_for_next_event」と「xcb_wait_for_event」はどちらも「get_event」を呼び出します。

「get_event」がイベントを見つけると、内部リンク リストが次のイベントを指すように変更されます。ただし、イベントが利用可能かどうかに関係なく、イベントキューをまったく変更しないことをお勧めします。

そのため、次のような機能を XCB に追加することを提案します。

void* NULL_POINTER = (void*) 0;

int xcb_test_for_event(xcb_connection_t* c) {

    int r = 0;

    if (c != NULL_POINTER) {

        struct _xcb_in in = c->in;
        struct event_list* l = in.events;

        if (l != NULL_POINTER) {

            xcb_generic_event_t* e = l->event;

            if (e != NULL_POINTER) {

                r = 1;
            }
        }
    }

    return r;
}

これにより、次のような無限ループを記述できます。

while (!xcb_test_for_event(connection)) {

    sleep(t);
}

これは、古い Xlib 関数に匹敵します。

int n = XEventsQueued(d, QueuedAfterReading);

イベントキュー内のイベント数を確認しました。「XEventsQueued」関数は、既にキューにイベントがある場合、常に入力/出力なしですぐに戻ります。

ありがとうクリスチャン

于 2013-04-05T13:06:41.327 に答える