web-dev-qa-db-ja.com

なぜpollでpoll_waitを呼び出す必要があるのですか?

LDD3では、そのようなコードを見ました

static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
    struct scull_pipe *dev = filp->private_data;
    unsigned int mask = 0;

    /*
     * The buffer is circular; it is considered full
     * if "wp" is right behind "rp" and empty if the
     * two are equal.
     */
    down(&dev->sem);
    poll_wait(filp, &dev->inq,  wait);
    poll_wait(filp, &dev->outq, wait);
    if (dev->rp != dev->wp)
        mask |= POLLIN | POLLRDNORM;    /* readable */
    if (spacefree(dev))
        mask |= POLLOUT | POLLWRNORM;   /* writable */
    up(&dev->sem);
    return mask;
}

しかし、poll_waitは待機せず、すぐに戻ると書かれています。では、なぜそれを呼び出す必要があるのでしょうか。なぜマスクを返せないのですか?

11
demonguy

poll_waitは、プロセスをウェイクアップできるデバイスのリストにデバイス(「構造体ファイル」で表される)を追加します。

プロセスは、poll(またはselectまたはepollなど)を使用して、待機したいリストに一連のファイル記述子を追加できるという考え方です。各ドライバーのポーリングエントリが呼び出されます。それぞれが(poll_waitを介して)ウェイターリストに追加されます。

次に、コアカーネルがプロセスを1か所でブロックします。そうすれば、どのデバイスでもプロセスをウェイクアップできます。ゼロ以外のマスクビットを返す場合、それはそれらの「準備完了」属性(読み取り可能/書き込み可能など)が適用されることを意味します

したがって、擬似コードでは、大まかに次のようになります。

foreach fd:
    find device corresponding to fd
    call device poll function to setup wait queues (with poll_wait) and to collect its "ready-now" mask

while time remaining in timeout and no devices are ready:
    sleep

return from system call (either due to timeout or to ready devices)
13
Gil Hamilton

file_operationを返すと、poll0はスリープします

これが私を混乱させたものです。

ゼロ以外を返すと、何らかのイベントが発生し、ウェイクアップしたことを意味します。

これを見ると、何かがプロセスを待機キューに結び付けている必要があることは明らかであり、それはpoll_waitです。

また、struct fileは、ファイルシステムファイルだけでなく、「プロセスと開いているファイル間の接続」を表すため、プロセスを識別するために使用されるpidが含まれていることにも注意してください。

最小限の実行可能な例で遊ぶことも、物事を明確にするのに役立つかもしれません: https://stackoverflow.com/a/44645336/895245