2015-05-14 328 views
7

在LDD3,我看到這樣的代碼爲什麼我們需要在poll中調用poll_wait?

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不會等待,將立即返回。那爲什麼我們需要打電話呢?爲什麼我們不能只返回面具?

回答

10

poll_wait將您的設備(由「struct file」表示)添加到可以喚醒進程的設備列表中。

想法是,該進程可以使用輪詢(或選擇或epoll等)來添加一堆文件描述符到它希望等待的列表中。每個驅動程序的輪詢條目都會被調用。每個人都將其自身(通過poll_wait)添加到服務員列表中。

然後核心內核在一個地方阻塞進程。這樣,任何一個設備都可以喚醒進程。如果您返回非零掩碼位,則表示這些「就緒」屬性(可讀/可寫/等)現在應用現在

所以,在僞代碼,它大致是這樣的:當有它正在等待發生在任何FD的的預期事件或它擊中超時

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) 
+0

然後做的過程中睡眠時? – demonguy

+0

@demonguy查看我的更新回答 –

+0

您的意思是說,來自用戶空間的查詢調用會阻止進程,對不對? – demonguy

-1

poll_wait觸發。

檢查掩碼以瞭解哪個事件觸發了poll_wait。如果您不希望poll_wait觸發此類事件,則可以在註冊文件描述符的同時對其進行配置以輪詢fd。

+1

這是完全錯誤的。 'poll_wait'根本不'觸發'。它只是將一個等待隊列添加到'poll_table'。 – EML

2

pollfile_operation睡覺,如果你回到0

這是混淆了我。

當你返回非零時,它意味着某個事件被觸發了,並且它被喚醒。

一旦你看到這一點,很明顯,有什麼東西必須綁定到等待隊列的過程,那東西是poll_wait

還要記住struct file代表「進程和打開文件之間的連接」,而不僅僅是文件系統文件,因此它包含用於標識進程的pid。

以最小的可運行的例子播放也可能有助於明確的東西:https://stackoverflow.com/a/44645336/895245

相關問題