2015-05-14 20 views
7

In LDD3, sah ich solche CodesWarum müssen wir poll_wait in der Umfrage aufrufen?

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; 
} 

Aber es sagt poll_wait nicht warten und wird sofort zurück. Warum müssen wir es dann nennen? Warum können wir nicht einfach die Maske zurückgeben?

Antwort

10

poll_wait fügt Ihr Gerät (dargestellt durch die "struct file") zu der Liste derjenigen hinzu, die den Prozess aufwecken können.

Die Idee ist, dass der Prozess mit Poll (oder select oder epoll etc) eine Reihe von Dateideskriptoren zu der Liste hinzufügen kann, auf die er warten möchte. Der Abfrageeintrag für jeden Treiber wird aufgerufen. Jeder fügt sich selbst (via poll_wait) zur Kellnerliste hinzu.

Dann blockiert der Core-Kernel den Prozess an einer Stelle. Auf diese Weise kann jedes der Geräte den Prozess aufwecken. Wenn Sie Nicht-Null-Maskenbits zurückgeben, bedeutet das, dass diese "Bereit" -Attribute (lesbar/schreibbar/etc) jetzt sind.

in Pseudo-Code So ist es etwa so:

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

Wenn dann funktioniert der Prozess Schlaf? – demonguy

+0

@demonguy Siehe meine aktualisierte Antwort –

+0

Sie meinen, Poll-Aufruf von User Space wird den Prozess blockieren, richtig? – demonguy

-1

poll_wait auslöst, wenn ein erwartetes Ereignis auf einem der fd des aufgetreten ist wartet auf OR trifft es Timeout.

Überprüfen Sie die Maske, um zu wissen, welches Ereignis poll_wait ausgelöst hat. Wenn Sie nicht möchten, dass poll_wait bei einem solchen Ereignis ausgelöst wird, können Sie es konfigurieren, während Sie den Dateideskriptor für die Abfrage von fd registrieren.

+1

Das ist völlig falsch. 'poll_wait' wird überhaupt nicht 'ausgelöst'. Es fügt der 'poll_table' einfach eine Warteschlange hinzu. – EML

2

Die pollfile_operation schläft, wenn Sie zurückkommen 0

Das ist, was mich verwirrte.

Wenn Sie nicht Null zurückgeben, bedeutet dies, dass ein Ereignis ausgelöst wurde und es aufwacht.

Sobald Sie dies sehen, ist es klar, dass etwas den Prozess an die Warteschlange binden muss, und das Ding ist poll_wait.

Denken Sie auch daran, dass struct file "eine Verbindung zwischen einem Prozess und einer geöffneten Datei" darstellt, nicht nur eine Dateisystemdatei und als solche die PID enthält, die zur Identifizierung des Prozesses verwendet wird.

Spielen mit einem minimalen runnable Beispiel könnte auch klar, Dinge aufhelfen: https://stackoverflow.com/a/44645336/895245