dispositivo, \texttt{/dev/epoll}, per ottenere un file descriptor da
utilizzare con le funzioni dell'interfaccia,\footnote{il backporting
dell'interfaccia per il kernel 2.4, non ufficiale, utilizza sempre questo
- file.} ma poi si è passati all'uso una apposita \textit{system call}. Il
-primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello di
-chiamare la funzione \funcd{epoll\_create}, il cui prototipo è:
-\begin{prototype}{sys/epoll.h}
- {int epoll\_create(int size)}
+ file.} ma poi si è passati all'uso di apposite \textit{system call}. Il
+primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello
+ottenere detto file descriptor chiamando una delle funzioni
+\funcd{epoll\_create} e \funcd{epoll\_create1},\footnote{l'interfaccia di
+ \textit{epoll} è stata inserita nel kernel a partire dalla versione 2.5.44,
+ ed il supporto è stato aggiunto alle \acr{glibc} 2.3.2.} i cui prototipi
+sono:
+\begin{functions}
+ \headdecl{sys/epoll.h}
+
+ \funcdecl{int epoll\_create(int size)}
+ \funcdecl{int epoll\_create1(int flags)}
Apre un file descriptor per \textit{epoll}.
- \bodydesc{La funzione restituisce un file descriptor in caso di successo, o
- $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \bodydesc{Le funzioni restituiscono un file descriptor per \textit{epoll} in
+ caso di successo, o $-1$ in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EINVAL}] si è specificato un valore di \param{size} non
- positivo.
+ positivo o non valido per \param{flags}.
\item[\errcode{ENFILE}] si è raggiunto il massimo di file descriptor aperti
nel sistema.
+ \item[\errcode{EMFILE}] si è raggiunto il limite sul numero massimo di
+ istanze di \textit{epoll} per utente stabilito da
+ \procfile{/proc/sys/fs/epoll/max\_user\_instances}.
\item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel per creare
l'istanza.
\end{errlist}
}
-\end{prototype}
+\end{functions}
-La funzione restituisce un file descriptor speciale,\footnote{esso non è
- associato a nessun file su disco, inoltre a differenza dei normali file
- descriptor non può essere inviato ad un altro processo attraverso un socket
- locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche \textit{epoll
- descriptor}, che viene associato alla infrastruttura utilizzata dal kernel
-per gestire la notifica degli eventi; l'argomento \param{size} serve a dare
-l'indicazione del numero di file descriptor che si vorranno tenere sotto
-controllo, ma costituisce solo un suggerimento per semplificare l'allocazione
-di risorse sufficienti, non un valore massimo.
+Entrambe le funzioni restituiscono un file descriptor speciale,\footnote{esso
+ non è associato a nessun file su disco, inoltre a differenza dei normali
+ file descriptor non può essere inviato ad un altro processo attraverso un
+ socket locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche
+\textit{epoll descriptor}, che viene associato alla infrastruttura utilizzata
+dal kernel per gestire la notifica degli eventi. Nel caso di
+\func{epoll\_create} l'argomento \param{size} serviva a dare l'indicazione del
+numero di file descriptor che si vorranno tenere sotto controllo, e costituiva
+solo un suggerimento per semplificare l'allocazione di risorse sufficienti,
+non un valore massimo.\footnote{ma a partire dal kernel 2.6.8 esso viene
+ totalmente ignorato e l'allocazione è sempre dinamica.}
+
+La seconda versione della funzione, \func{epoll\_create1} è stata
+introdotta\footnote{è disponibile solo a partire dal kernel 2.6.27.} come
+estensione della precedente, per poter passare dei flag di controllo come
+maschera binaria in fase di creazione del file descriptor. Al momento l'unico
+valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
+che consente di impostare in maniera atomica sul file descriptor il flag di
+\itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
+\const{O\_CLOEXEC} in tab.~\ref{tab:file_open_flags}), senza che sia
+necessaria una successiva chiamata a \func{fcntl}.
Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
indicare quali file descriptor mettere sotto osservazione e quali operazioni
\item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel gestire
l'operazione richiesta.
\item[\errcode{EPERM}] il file \param{fd} non supporta \textit{epoll}.
+ \item[\errcode{ENOSPC}] si è raggiunto il limite massimo di registrazioni
+ per utente di file descriptor da osservere imposto da
+ \procfile{/proc/sys/fs/epoll/max\_user\_watches}.
\end{errlist}
}
\end{prototype}
indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto
sotto controllo. L'argomento viene ignorato con l'operazione
\const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto
- che questo fosse un puntatore valido, anche se poi veniva ignorato, a
- partire dal 2.6.9 si può specificare anche un valore \texttt{NULL}.}
+ che questo fosse un puntatore valido, anche se poi veniva ignorato; a
+ partire dal 2.6.9 si può specificare anche un valore \texttt{NULL} ma se si
+ vuole mantenere la compatibilità con le versioni precedenti occorre usare un
+ puntatore valido.}
\begin{figure}[!htb]
\footnotesize \centering
tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, serve ad indicare a
quale file descriptor si intende fare riferimento, ed in astratto può
contenere un valore qualsiasi che permetta di identificarlo, di norma comunque
-si usa come valore lo stesso \param{fd}.
+si usa come valore lo stesso argomento \param{fd}, che ha un significato
+immediato.
\begin{table}[htb]
\centering
\const{EPOLLRDHUP} & L'altro capo di un socket di tipo
\const{SOCK\_STREAM} (vedi sez.~\ref{sec:sock_type})
ha chiuso la connessione o il capo in scrittura
- della stessa (vedi sez.~\ref{sec:TCP_shutdown}).\\
+ della stessa (vedi
+ sez.~\ref{sec:TCP_shutdown}).\footnotemark\\
\const{EPOLLPRI} & Ci sono \itindex{out-of-band} dati urgenti
disponibili in lettura (analogo di
\const{POLLPRI}); questa condizione viene comunque
(analogo di \const{POLLERR}); questa condizione
viene comunque riportata in uscita, e non è
necessaria impostarla in ingresso.\\
- \const{EPOLLHUP} & Si è verificata una condizione di hung-up.\\
+ \const{EPOLLHUP} & Si è verificata una condizione di hung-up; questa
+ condizione viene comunque riportata in uscita, e non
+ è necessaria impostarla in ingresso.\\
\const{EPOLLET} & Imposta la notifica in modalità \textit{edge
triggered} per il file descriptor associato.\\
\const{EPOLLONESHOT}& Imposta la modalità \textit{one-shot} per il file
\label{tab:epoll_events}
\end{table}
-\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.2.}
+\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.17,
+ ed è utile per riconoscere la chiusura di una connessione dall'altro capo
+ quando si lavora in modalità \textit{edge triggered}.}
+
+\footnotetext[48]{questa modalità è disponibile solo a partire dal kernel
+ 2.6.2.}
Le modalità di utilizzo di \textit{epoll} prevedono che si definisca qual'è
l'insieme dei file descriptor da tenere sotto controllo tramite un certo
Come già per \func{select} e \func{poll} anche per l'interfaccia di
\textit{epoll} si pone il problema di gestire l'attesa di segnali e di dati
-contemporaneamente, per far questo di nuovo è necessaria una variante della
-funzione di attesa che consenta di reimpostare all'uscita una maschera di
-segnali, analoga alle precedenti estensioni \func{pselect} e \func{ppoll} di
+contemporaneamente per le osservazioni fatte in sez.~\ref{sec:file_select},
+per fare questo di nuovo è necessaria una variante della funzione di attesa
+che consenta di reimpostare all'uscita una maschera di segnali, analoga alle
+estensioni \func{pselect} e \func{ppoll} che abbiamo visto in precedenza per
\func{select} e \func{poll}; in questo caso la funzione si chiama
\funcd{epoll\_pwait}\footnote{la funziona è stata introdotta a partire dal
kernel 2.6.19, ed è come tutta l'interfaccia di \textit{epoll}, specifica di