Aggiornamento note copyright e I/O Asyncrono
[gapil.git] / fileadv.tex
index 88f6307d5383a74301d8e738a74138b49f6833ae..dd0550bb217889eec63594533ddfcb13cb6ddd03 100644 (file)
@@ -1,6 +1,6 @@
 %% fileadv.tex
 %%
-%% Copyright (C) 2000-2014 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2015 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -8,6 +8,7 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{La gestione avanzata dei file}
 \label{cha:file_advanced}
 In questo capitolo affronteremo le tematiche relative alla gestione avanzata
@@ -3493,50 +3494,50 @@ raggruppati in un solo evento.
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
-% vedere anche http://davmac.org/davpage/linux/async-io.html  e
-% http://www.ibm.com/developerworks/linux/library/l-async/ 
-
-
 Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
 dell'I/O simultaneo su molti file è costituita dal cosiddetto \textsl{I/O
-  asincrono}. Il concetto base dell'\textsl{I/O asincrono} è che le funzioni
-di I/O non attendono il completamento delle operazioni prima di ritornare,
-così che il processo non viene bloccato.  In questo modo diventa ad esempio
-possibile effettuare una richiesta preventiva di dati, in modo da poter
-effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
-
-Benché la modalità di apertura asincrona di un file possa risultare utile in
-varie occasioni (in particolar modo con i socket e gli altri file per i quali
-le funzioni di I/O sono \index{system~call~lente} \textit{system call} lente),
-essa è comunque limitata alla notifica della disponibilità del file descriptor
-per le operazioni di I/O, e non ad uno svolgimento asincrono delle medesime.
-Lo standard POSIX.1b definisce una interfaccia apposita per l'I/O asincrono
-vero e proprio, che prevede un insieme di funzioni dedicate per la lettura e
-la scrittura dei file, completamente separate rispetto a quelle usate
-normalmente.
+  asincrono} o ``AIO''. Il concetto base dell'\textsl{I/O asincrono} è che le
+funzioni di I/O non attendono il completamento delle operazioni prima di
+ritornare, così che il processo non viene bloccato.  In questo modo diventa ad
+esempio possibile effettuare una richiesta preventiva di dati, in modo da
+poter effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
+
+Benché la modalità di apertura asincrona di un file vista in
+sez.~\ref{sec:signal_driven_io} possa risultare utile in varie occasioni (in
+particolar modo con i socket e gli altri file per i quali le funzioni di I/O
+sono \index{system~call~lente} \textit{system call} lente), essa è comunque
+limitata alla notifica della disponibilità del file descriptor per le
+operazioni di I/O, e non ad uno svolgimento asincrono delle medesime.  Lo
+standard POSIX.1b definisce una interfaccia apposita per l'I/O asincrono vero
+e proprio,\footnote{questa è stata ulteriormente perfezionata nelle successive
+  versioni POSIX.1-2001 e POSIX.1-2008.} che prevede un insieme di funzioni
+dedicate per la lettura e la scrittura dei file, completamente separate
+rispetto a quelle usate normalmente.
 
 In generale questa interfaccia è completamente astratta e può essere
-implementata sia direttamente nel kernel, che in user space attraverso l'uso
-di \itindex{thread} \textit{thread}. Per le versioni del kernel meno recenti
-esiste una implementazione di questa interfaccia fornita delle \acr{glibc},
-che è realizzata completamente in user space, ed è accessibile linkando i
-programmi con la libreria \file{librt}. Nelle versioni più recenti (a partire
-dalla 2.5.32) è stato introdotto direttamente nel kernel un nuovo layer per
-l'I/O asincrono.
-
-Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
-attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per
-\textit{asyncronous I/O control block}), che viene passata come argomento a
-tutte le funzioni dell'interfaccia. La sua definizione, come effettuata in
-\headfile{aio.h}, è riportata in fig.~\ref{fig:file_aiocb}. Nello steso file è
-definita la macro \macro{\_POSIX\_ASYNCHRONOUS\_IO}, che dichiara la
-disponibilità dell'interfaccia per l'I/O asincrono.
+implementata sia direttamente nel kernel che in user space attraverso l'uso di
+\itindex{thread} \textit{thread}. Per le versioni del kernel meno recenti
+esiste una implementazione di questa interfaccia fornita completamente delle
+\acr{glibc} a partire dalla versione 2.1, che è realizzata completamente in
+user space, ed è accessibile linkando i programmi con la libreria
+\file{librt}. A partire dalla versione 2.5.32 è stato introdotto nel kernel
+una nuova infrastruttura per l'I/O asincrono, ma ancora il supporto è parziale
+ed insufficiente ad implementare tutto l'AIO POSIX.
+
+Lo standard POSIX prevede che tutte le operazioni di I/O asincrono siano
+controllate attraverso l'uso di una apposita struttura \struct{aiocb} (il cui
+nome sta per \textit{asyncronous I/O control block}), che viene passata come
+argomento a tutte le funzioni dell'interfaccia. La sua definizione, come
+effettuata in \headfile{aio.h}, è riportata in
+fig.~\ref{fig:file_aiocb}. Nello steso file è definita la macro
+\macro{\_POSIX\_ASYNCHRONOUS\_IO}, che dichiara la disponibilità
+dell'interfaccia per l'I/O asincrono.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/aiocb.h}
-  \end{minipage} 
+  \end{minipage}
   \normalsize 
   \caption{La struttura \structd{aiocb}, usata per il controllo dell'I/O
     asincrono.}
@@ -3557,16 +3558,16 @@ l'indirizzo del buffer usato per l'I/O, ed in \var{aio\_nbytes} la lunghezza
 del blocco di dati da trasferire.
 
 Il campo \var{aio\_reqprio} permette di impostare la priorità delle operazioni
-di I/O.\footnote{in generale perché ciò sia possibile occorre che la
-  piattaforma supporti questa caratteristica, questo viene indicato definendo
-  le macro \macro{\_POSIX\_PRIORITIZED\_IO}, e
-  \macro{\_POSIX\_PRIORITY\_SCHEDULING}.} La priorità viene impostata a
-partire da quella del processo chiamante (vedi sez.~\ref{sec:proc_priority}),
-cui viene sottratto il valore di questo campo.  Il campo
-\var{aio\_lio\_opcode} è usato solo dalla funzione \func{lio\_listio}, che,
-come vedremo, permette di eseguire con una sola chiamata una serie di
-operazioni, usando un vettore di \textit{control block}. Tramite questo campo
-si specifica quale è la natura di ciascuna di esse.
+di I/O, in generale perché ciò sia possibile occorre che la piattaforma
+supporti questa caratteristica, questo viene indicato dal fatto che le macro
+\macro{\_POSIX\_PRIORITIZED\_IO}, e \macro{\_POSIX\_PRIORITY\_SCHEDULING} sono
+definite. La priorità viene impostata a partire da quella del processo
+chiamante (vedi sez.~\ref{sec:proc_priority}), cui viene sottratto il valore
+di questo campo.  Il campo \var{aio\_lio\_opcode} è usato solo dalla funzione
+\func{lio\_listio}, che, come vedremo, permette di eseguire con una sola
+chiamata una serie di operazioni, usando un vettore di \textit{control
+  block}. Tramite questo campo si specifica quale è la natura di ciascuna di
+esse.
 
 Infine il campo \var{aio\_sigevent} è una struttura di tipo \struct{sigevent}
 (illustrata in in fig.~\ref{fig:struct_sigevent}) che serve a specificare il
@@ -3576,45 +3577,44 @@ stessa si veda quanto già visto in proposito in sez.~\ref{sec:sig_timer_adv}.
 
 Le due funzioni base dell'interfaccia per l'I/O asincrono sono
 \funcd{aio\_read} ed \funcd{aio\_write}.  Esse permettono di richiedere una
-lettura od una scrittura asincrona di dati, usando la struttura \struct{aiocb}
+lettura od una scrittura asincrona di dati usando la struttura \struct{aiocb}
 appena descritta; i rispettivi prototipi sono:
-\begin{functions}
-  \headdecl{aio.h}
 
-  \funcdecl{int aio\_read(struct aiocb *aiocbp)}
-  Richiede una lettura asincrona secondo quanto specificato con \param{aiocbp}.
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{int aio\_read(struct aiocb *aiocbp)}
+\fdesc{Richiede una lettura asincrona.} 
+\fdecl{int aio\_write(struct aiocb *aiocbp)}
+\fdesc{Richiede una scrittura asincrona.} 
+}
 
-  \funcdecl{int aio\_write(struct aiocb *aiocbp)}
-  Richiede una scrittura asincrona secondo quanto specificato con
-  \param{aiocbp}.
-  
-  \bodydesc{Le funzioni restituiscono 0 in caso di successo, e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
   \begin{errlist}
+  \item[\errcode{EAGAIN}] la coda delle richieste è momentaneamente piena.
   \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato.
-  \item[\errcode{ENOSYS}] la funzione non è implementata.
   \item[\errcode{EINVAL}] si è specificato un valore non valido per i campi
     \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
-  \item[\errcode{EAGAIN}] la coda delle richieste è momentaneamente piena.
+  \item[\errcode{ENOSYS}] la funzione non è implementata.
   \end{errlist}
 }
-\end{functions}
+\end{funcproto}
+
 
 Entrambe le funzioni ritornano immediatamente dopo aver messo in coda la
 richiesta, o in caso di errore. Non è detto che gli errori \errcode{EBADF} ed
 \errcode{EINVAL} siano rilevati immediatamente al momento della chiamata,
 potrebbero anche emergere nelle fasi successive delle operazioni. Lettura e
 scrittura avvengono alla posizione indicata da \var{aio\_offset}, a meno che
-il file non sia stato aperto in \itindex{append~mode} \textit{append mode}
-(vedi sez.~\ref{sec:file_open_close}), nel qual caso le scritture vengono
-effettuate comunque alla fine de file, nell'ordine delle chiamate a
-\func{aio\_write}.
+il file non sia stato aperto in \textit{append mode} (vedi
+sez.~\ref{sec:file_open_close}), nel qual caso le scritture vengono effettuate
+comunque alla fine del file, nell'ordine delle chiamate a \func{aio\_write}.
 
 Si tenga inoltre presente che deallocare la memoria indirizzata da
 \param{aiocbp} o modificarne i valori prima della conclusione di una
 operazione può dar luogo a risultati impredicibili, perché l'accesso ai vari
 campi per eseguire l'operazione può avvenire in un momento qualsiasi dopo la
-richiesta.  Questo comporta che non si devono usare per \param{aiocbp}
+richiesta. Questo comporta che non si devono usare per \param{aiocbp}
 \index{variabili!automatiche} variabili automatiche e che non si deve
 riutilizzare la stessa struttura per un'altra operazione fintanto che la
 precedente non sia stata ultimata. In generale per ogni operazione si deve
@@ -3626,111 +3626,134 @@ eseguite in maniera corretta; per verificarne l'esito l'interfaccia prevede
 altre due funzioni, che permettono di controllare lo stato di esecuzione. La
 prima è \funcd{aio\_error}, che serve a determinare un eventuale stato di
 errore; il suo prototipo è:
-\begin{prototype}{aio.h}
-  {int aio\_error(const struct aiocb *aiocbp)}  
 
-  Determina lo stato di errore delle operazioni di I/O associate a
-  \param{aiocbp}.
-  
-  \bodydesc{La funzione restituisce 0 se le operazioni si sono concluse con
-    successo, altrimenti restituisce il codice di errore relativo al loro
-    fallimento.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{int aio\_error(const struct aiocb *aiocbp)} 
+\fdesc{Determina lo stato di errore di una operazione di I/O asincrono.} 
+}
 
-Se l'operazione non si è ancora completata viene restituito l'errore di
-\errcode{EINPROGRESS}. La funzione ritorna zero quando l'operazione si è
+{La funzione ritorna $0$ se le operazioni si sono concluse con successo,
+  altrimenti restituisce \errval{EINPROGRESS} se non sono concluse,
+  \errcode{ECANCELED} se sono state cancellate o il relativo codice di errore
+  se sono fallite.}
+\end{funcproto}
+
+Se l'operazione non si è ancora completata viene sempre restituito l'errore di
+\errcode{EINPROGRESS}, mentre se è stata cancellata ritorna
+\errcode{ECANCELED}. La funzione ritorna zero quando l'operazione si è
 conclusa con successo, altrimenti restituisce il codice dell'errore
 verificatosi, ed esegue la corrispondente impostazione di \var{errno}. Il
 codice può essere sia \errcode{EINVAL} ed \errcode{EBADF}, dovuti ad un valore
 errato per \param{aiocbp}, che uno degli errori possibili durante l'esecuzione
 dell'operazione di I/O richiesta, nel qual caso saranno restituiti, a seconda
 del caso, i codici di errore delle \textit{system call} \func{read},
-\func{write} e \func{fsync}.
+\func{write}, \func{fsync} e \func{fdatasync}.
 
 Una volta che si sia certi che le operazioni siano state concluse (cioè dopo
 che una chiamata ad \func{aio\_error} non ha restituito
 \errcode{EINPROGRESS}), si potrà usare la funzione \funcd{aio\_return}, che
 permette di verificare il completamento delle operazioni di I/O asincrono; il
 suo prototipo è:
-\begin{prototype}{aio.h}
-{ssize\_t aio\_return(const struct aiocb *aiocbp)} 
 
-Recupera il valore dello stato di ritorno delle operazioni di I/O associate a
-\param{aiocbp}.
-  
-\bodydesc{La funzione restituisce lo stato di uscita dell'operazione
-  eseguita.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{ssize\_t aio\_return(const struct aiocb *aiocbp)}
+\fdesc{Ottiene lo stato dei risultati di una operazione di I/O asincrono.} 
+}
 
-La funzione deve essere chiamata una sola volte per ciascuna operazione
-asincrona, essa infatti fa sì che il sistema rilasci le risorse ad essa
-associate. É per questo motivo che occorre chiamare la funzione solo dopo che
-l'operazione cui \param{aiocbp} fa riferimento si è completata. Una chiamata
-precedente il completamento delle operazioni darebbe risultati indeterminati.
+{La funzione ritorna lo stato di uscita dell'operazione eseguita (il valore
+  che avrebbero restituito le equivalenti funzioni eseguite in maniera
+  sincrona).}
+\end{funcproto}
+
+La funzione recupera il valore dello stato di ritorno delle operazioni di I/O
+associate a \param{aiocbp} e deve essere chiamata una sola volta per ciascuna
+operazione asincrona, essa infatti fa sì che il sistema rilasci le risorse ad
+essa associate. É per questo motivo che occorre chiamare la funzione solo dopo
+che l'operazione cui \param{aiocbp} fa riferimento si è completata
+verificandolo con \func{aio\_error}, ed usarla una sola volta. Una chiamata
+precedente il completamento delle operazioni darebbe risultati indeterminati,
+così come chiamarla più di una volta.
 
 La funzione restituisce il valore di ritorno relativo all'operazione eseguita,
 così come ricavato dalla sottostante \textit{system call} (il numero di byte
-letti, scritti o il valore di ritorno di \func{fsync}).  É importante chiamare
-sempre questa funzione, altrimenti le risorse disponibili per le operazioni di
-I/O asincrono non verrebbero liberate, rischiando di arrivare ad un loro
-esaurimento.
+letti, scritti o il valore di ritorno di \func{fsync} o \func{fdatasync}).  É
+importante chiamare sempre questa funzione, altrimenti le risorse disponibili
+per le operazioni di I/O asincrono non verrebbero liberate, rischiando di
+arrivare ad un loro esaurimento.
 
 Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a
 disposizione un'altra operazione, quella di sincronizzazione dell'I/O,
 compiuta dalla funzione \funcd{aio\_fsync}, che ha lo stesso effetto della
 analoga \func{fsync}, ma viene eseguita in maniera asincrona; il suo prototipo
 è:
-\begin{prototype}{aio.h}
-{int aio\_fsync(int op, struct aiocb *aiocbp)} 
 
-Richiede la sincronizzazione dei dati per il file indicato da \param{aiocbp}.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore, che può essere, con le stesse modalità di \func{aio\_read},
-  \errval{EAGAIN}, \errval{EBADF} o \errval{EINVAL}.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{int aio\_fsync(int op, struct aiocb *aiocbp)} 
+\fdesc{Richiede la sincronizzazione dei dati su disco.} 
+}
 
-La funzione richiede la sincronizzazione delle operazioni di I/O, ritornando
-immediatamente. L'esecuzione effettiva della sincronizzazione dovrà essere
-verificata con \func{aio\_error} e \func{aio\_return} come per le operazioni
-di lettura e scrittura. L'argomento \param{op} permette di indicare la
-modalità di esecuzione, se si specifica il valore \const{O\_DSYNC} le
-operazioni saranno completate con una chiamata a \func{fdatasync}, se si
-specifica \const{O\_SYNC} con una chiamata a \func{fsync} (per i dettagli vedi
-sez.~\ref{sec:file_sync}).
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà gli stessi valori visti \func{aio\_read} con lo
+  stesso significato.
+}
+\end{funcproto}
 
-Il successo della chiamata assicura la sincronizzazione delle operazioni fino
-allora richieste, niente è garantito riguardo la sincronizzazione dei dati
-relativi ad eventuali operazioni richieste successivamente. Se si è
-specificato un meccanismo di notifica questo sarà innescato una volta che le
-operazioni di sincronizzazione dei dati saranno completate.
+La funzione richiede la sincronizzazione dei dati delle operazioni di I/O
+relative al file descriptor indicato in \texttt{aiocbp->aio\_fildes},
+ritornando immediatamente. Si tenga presente che la funzione mette
+semplicemente in coda la richiesta, l'esecuzione effettiva della
+sincronizzazione dovrà essere verificata con \func{aio\_error} e
+\func{aio\_return} come per le operazioni di lettura e
+scrittura. L'argomento \param{op} permette di indicare la modalità di
+esecuzione, se si specifica il valore \const{O\_DSYNC} le operazioni saranno
+completate con una chiamata a \func{fdatasync}, se si specifica
+\const{O\_SYNC} con una chiamata a \func{fsync} (per i dettagli vedi
+sez.~\ref{sec:file_sync}).
 
-In alcuni casi può essere necessario interrompere le operazioni (in genere
-quando viene richiesta un'uscita immediata dal programma), per questo lo
-standard POSIX.1b prevede una funzione apposita, \funcd{aio\_cancel}, che
+Il successo della chiamata assicura la richiesta di sincronizzazione dei dati
+relativi operazioni di I/O asincrono richieste fino a quel momento, niente è
+garantito riguardo la sincronizzazione dei dati relativi ad eventuali
+operazioni richieste successivamente. Se si è specificato un meccanismo di
+notifica questo sarà innescato una volta che le operazioni di sincronizzazione
+dei dati saranno completate (\texttt{aio\_sigevent} è l'unico altro campo
+di \param{aiocbp} che viene usato.
+
+In alcuni casi può essere necessario interrompere le operazioni di I/O (in
+genere quando viene richiesta un'uscita immediata dal programma), per questo
+lo standard POSIX.1b prevede una funzione apposita, \funcd{aio\_cancel}, che
 permette di cancellare una operazione richiesta in precedenza; il suo
 prototipo è:
-\begin{prototype}{aio.h}
-{int aio\_cancel(int fildes, struct aiocb *aiocbp)} 
 
-Richiede la cancellazione delle operazioni sul file \param{fildes} specificate
-da \param{aiocbp}.
-  
-\bodydesc{La funzione restituisce il risultato dell'operazione con un codice
-  di positivo, e -1 in caso di errore, che avviene qualora si sia specificato
-  un valore non valido di \param{fildes}, imposta \var{errno} al valore
-  \errval{EBADF}.}
-\end{prototype}
+
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{int aio\_cancel(int fd, struct aiocb *aiocbp)}
+\fdesc{Richiede la cancellazione delle operazioni di I/O asincrono.} 
+}
+
+{La funzione ritorna un intero positivo che indica il risultato
+  dell'operazione in caso di successo e $-1$ per un errore, nel qual caso
+  \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido.
+  \item[\errcode{ENOSYS}] la funzione non è implementata.
+  \end{errlist}
+}
+\end{funcproto}
 
 La funzione permette di cancellare una operazione specifica sul file
-\param{fildes}, o tutte le operazioni pendenti, specificando \val{NULL} come
-valore di \param{aiocbp}.  Quando una operazione viene cancellata una
-successiva chiamata ad \func{aio\_error} riporterà \errcode{ECANCELED} come
-codice di errore, ed il suo codice di ritorno sarà -1, inoltre il meccanismo
-di notifica non verrà invocato. Se si specifica una operazione relativa ad un
-altro file descriptor il risultato è indeterminato.  In caso di successo, i
-possibili valori di ritorno per \func{aio\_cancel} (anch'essi definiti in
-\headfile{aio.h}) sono tre:
+\param{fd}, idicata con \param{aiocbp}, o tutte le operazioni pendenti,
+specificando \val{NULL} come valore di \param{aiocbp}. Quando una operazione
+viene cancellata una successiva chiamata ad \func{aio\_error} riporterà
+\errcode{ECANCELED} come codice di errore, ed mentre il valore di ritorno per
+\func{aio\_return} sarà -1, inoltre il meccanismo di notifica non verrà
+invocato. Se con \param{aiocbp} si specifica una operazione relativa ad un
+file descriptor diverso da \param{fd} il risultato è indeterminato.  In caso
+di successo, i possibili valori di ritorno per \func{aio\_cancel} (anch'essi
+definiti in \headfile{aio.h}) sono tre:
 \begin{basedescript}{\desclabelwidth{3.0cm}}
 \item[\const{AIO\_ALLDONE}] indica che le operazioni di cui si è richiesta la
   cancellazione sono state già completate,
@@ -3752,30 +3775,30 @@ Benché l'I/O asincrono preveda un meccanismo di notifica, l'interfaccia
 fornisce anche una apposita funzione, \funcd{aio\_suspend}, che permette di
 sospendere l'esecuzione del processo chiamante fino al completamento di una
 specifica operazione; il suo prototipo è:
-\begin{prototype}{aio.h}
-{int aio\_suspend(const struct aiocb * const list[], int nent, const struct
-    timespec *timeout)}
-  
-  Attende, per un massimo di \param{timeout}, il completamento di una delle
-  operazioni specificate da \param{list}.
-  
-  \bodydesc{La funzione restituisce 0 se una (o più) operazioni sono state
-    completate, e -1 in caso di errore nel qual caso \var{errno} assumerà uno
-    dei valori:
-    \begin{errlist}
+
+\begin{funcproto}{
+\fhead{aio.h}
+\fdecl{int aio\_suspend(const struct aiocb * const list[], int nent, 
+\phantom{int aio\_suspend(}const struct timespec *timeout)}
+\fdesc{Attende il completamento di una operazione di I/O asincrono.} 
+}
+
+{La funzione ritorna $0$ se una (o più) operazioni sono state completate e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EAGAIN}] nessuna operazione è stata completata entro
       \param{timeout}.
-    \item[\errcode{ENOSYS}] la funzione non è implementata.
     \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
-    \end{errlist}
-  }
-\end{prototype}
-
+    \item[\errcode{ENOSYS}] la funzione non è implementata.
+  \end{errlist}
+}
+\end{funcproto}
+  
 La funzione permette di bloccare il processo fintanto che almeno una delle
 \param{nent} operazioni specificate nella lista \param{list} è completata, per
 un tempo massimo specificato da \param{timout}, o fintanto che non arrivi un
-segnale.\footnote{si tenga conto che questo segnale può anche essere quello
-  utilizzato come meccanismo di notifica.} La lista deve essere inizializzata
+segnale (si tenga conto che questo segnale potrebbe essere anche quello
+utilizzato come meccanismo di notifica). La lista deve essere inizializzata
 con delle strutture \struct{aiocb} relative ad operazioni effettivamente
 richieste, ma può contenere puntatori nulli, che saranno ignorati. In caso si
 siano specificati valori non validi l'effetto è indefinito.  Un valore
@@ -3828,6 +3851,12 @@ il chiamante può richiedere la notifica del completamento di tutte le
 richieste, impostando l'argomento \param{sig} in maniera analoga a come si fa
 per il campo \var{aio\_sigevent} di \struct{aiocb}.
 
+% TODO: trattare libaio e le system call del kernel per l'I/O asincrono, vedi
+% http://lse.sourceforge.net/io/aio.html,
+% http://webfiveoh.com/content/guides/2012/aug/mon-13th/linux-asynchronous-io-and-libaio.html, 
+% https://code.google.com/p/kernel/wiki/AIOUserGuide,
+% http://bert-hubert.blogspot.de/2012/05/on-linux-asynchronous-file-io.html 
+
 
 \section{Altre modalità di I/O avanzato}
 \label{sec:file_advanced_io}