Sistemato HTML del sito, quasi completato l'I/O asincrono
[gapil.git] / fileadv.tex
index 578f867f0d011bd03e4fce75c534232245314ea6..a0c5f05952542ec2a59cb6906e3d02f3cfaaf658 100644 (file)
@@ -424,7 +424,7 @@ struct aiocb
 
 Le operazioni di I/O asincrono possono essere effettuate solo su un file già
 aperto, il cui file descriptor deve essere specificato tramite il campo
-\var{aio\_fildes}; il file deve inolte supportare la funzione \func{lseek},
+\var{aio\_fildes}; il file deve inoltre supportare la funzione \func{lseek},
 pertanto terminali e pipe sono esclusi. Non c'è limite al numero di operazioni
 contemporanee effettuabili su un singolo file.
 
@@ -444,9 +444,9 @@ da quella del processo chiamante (vedi \secref{sec:proc_priority}), cui viene
 sottratto il valore di questo campo.
 
 Il campo \var{aio\_lio\_opcode} è usato dalla funzione \func{lio\_listio}, che
-permette di attivare far partire una serie di operazioni in contemporanea su
-una lista di file. Tramite questo campo si specifica quale è la natura di
-ciascuna di esse.
+permette di far partire una serie di operazioni in contemporanea su una lista
+di file. Tramite questo campo si specifica quale è la natura di ciascuna di
+esse.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -463,50 +463,283 @@ struct sigevent
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \type{sigevent}, usata per .}
+  \caption{La struttura \type{sigevent}, usata per specificare le modailtà di
+    notifica degli eventi relativi alle operazioni di I/O asincrono.}
   \label{fig:file_sigevent}
 \end{figure}
 
-Infine il campo \var{aio\_sigevent} serve a specificare il modo in cui si
-vuole che la notifica del completamento delle operazioni richieste venga
-effettuata. La struttura è riportata in \secref{fig:file_sigevent}; il campo
-\var{sigev\_notify} è quello che indica le modalità della notifica, esso può
-assumere i tre valori:
+Infine il campo \var{aio\_sigevent} è una struttura di tipo \type{sigevent}
+che serve a specificare il modo in cui si vuole che venga effettuata la
+notifica del completamento delle operazioni richieste. La struttura è
+riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello
+che indica le modalità della notifica, esso può assumere i tre valori:
 \begin{basedescript}{\desclabelwidth{3.0cm}}
 \item[\macro{SIGEV\_NONE}]   Non viene inviata nessuna notifica.
-\item[\macro{SIGEV\_SIGNAL}] La notifica viene effettuata usando il segnale
-  specificato nel campo \var{sigev\_signo}.
+\item[\macro{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
+  chiamante il segnale specificato nel campo \var{sigev\_signo}, se il
+  manipolatore è installato con \macro{SA\_SIGINFO}, il gli verrà restituito
+  il valore di \var{sigev\_value} in come valore del campo \var{si\_value} per
+  \type{siginfo\_t}.
 \item[\macro{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo
   thread che esegue la funzione specificata da \var{sigev\_notify\_function},
   con gli attributi specificati da \var{sigev\_notify\_attribute}.
 \end{basedescript}
 
-
-Le due funzioni principali dell'interfaccia sono quelle per la lettura e
-scrittura, \func{aio\_read} e \func{aio\_write}, i cui prototipi sono:
+Le due funzioni base dell'interfaccia POSIX.1b per l'I/O asincrono sono
+\func{aio\_read} e \func{aio\_write}.  Esse servono a richiedere una lettura
+od una scrittura asincrona di dati usando la struttura \type{aiocb} appena
+descritta; i rispettivi prototipi sono:
 \begin{functions}
   \headdecl{aio.h}
 
   \funcdecl{int aio\_read(struct aiocb *aiocbp)}
-  Richiede una lettura asincrona sul file specificato tramite \param{aiocbp}.
+  Richiede una lettura asincrona secondo quanto specificato con \param{aiocbp}.
 
   \funcdecl{int aio\_write(struct aiocb *aiocbp)}
-  Richiede una scrittura asincrona sul file specificato tramite
+  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} viene settata ai valori:
   \begin{errlist}
-  \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
-    degli insiemi.
-  \item[\macro{ENOSYS}] La funzione è implementata.
-  \item[\macro{EINVAL}] Si è specificato un valore negativo non valido per i
-    campi \var{aio\_offset} o \var{aio\_reqprio}, di \param{aiocbp}.
+  \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato.
+  \item[\macro{ENOSYS}] La funzione non è implementata.
+  \item[\macro{EINVAL}] Si è specificato un valore non valido per i campi
+    \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
+  \item[\macro{EAGAIN}] La coda delle richieste è momentaneamente piena.
   \end{errlist}
-  ed inoltre \macro{ENOMEM}.}
-
+}
 \end{functions}
 
+Entrambe le funzioni ritornano immediatamente dopo aver messo in coda la
+richiesta, o in caso di errore. Non è detto che gli errori \macro{EBADF} ed
+\macro{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 \textit{append mode} (vedi
+\secref{sec:file_open}), nel qual caso le scritture vengono effettuate
+comunque alla fine de 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 occorre evitare di usare per \param{aiocbp}
+variabili automatiche, effettuando le chiamate all'interno di una subroutine,
+e che non si deve riutilizzare la stessa struttura per un'ulteriore operazione
+fintanto che la precedente non si sia ultimata. In generale per ogni
+operazione di I/O asincrono si deve utilizzare una ed una sola struttura
+\type{aiocb}.
+
+Si ricordi che, operando in modalità asincrona, il successo di queste funzioni
+non implica che le operazioni richieste siano state effettivamente eseguite in
+maniera corretta.  Per verificare l'esito delle operazioni l'interfaccia
+prevede altre due funzioni, che permettono di controllare lo stato di
+esecuzione. La prima è \func{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.}
+% }, che viene salvato  
+%     anche in \var{errno}, i valori possibili sono:
+%   \begin{errlist}
+%   \item[\macro{ENOSYS}] La funzione non è implementata.
+%   \item[\macro{EINPROGRESS}] L'operazione è ancora in corso.
+%   \item[\macro{EINVAL}] Si è specificato un valore non valido per i campi
+%     \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
+%   \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato.
+%   \end{errlist}
+%   più tutti quelli possibili per le sottostanti operazioni, .}
+\end{prototype}
+
+Se l'operazione non si è ancora completata viene restituito l'errore di
+\macro{EINPROGRESS}. La funzione ritorna zero quando l'operazione si è
+conclusa con successo, altrimenti restituisce il codice di errore, ed esegue
+il settaggio di \var{errno}. In caso caso di errore esso può essere sia uno
+dei precedentemente specificati \macro{EINVAL} ed \macro{EBADF}, dovuti ad un
+valore errato per \param{aiocbp} che uno dei possibili errori dovuti alle
+chiamate al sistema sottostanti l'esecuzione dell'operazione di I/O richiesta,
+relativi alle funzioni \func{read}, \func{write} e \func{fsync}.
+
+
+Una volta che si sia certi che le operazioni si siano concluse (cioè dopo che
+una chiamata ad \func{aio\_error} non ha restituito \macro{EINPROGRESS}, si
+può usare la seconda funzione dell'interfaccia, \func{aio\_return}, per
+verificare il completamento delle operazioni di I/O asincrono, il cui
+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}
+
+La funzione deve essere chiamata una sola volte per ciascuna operazione
+asincrona, essa infatti fa sì che il sistema rilasci le risorse associate a
+ciascuna operazione. Per questo motivo occorre chiamare la funzione solo dopo
+che l'operazione cui \param{aiocbp} fa riferimento si è completata. 
+
+La funzione restituisce il valore di ritorno relativa all'operazione eseguita,
+così come ricavato dalla sottostante 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.
+
+Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a
+disposizione un'altra operazione, quella di sincronizzazione delll'I/O, essa è
+compiuta dalla funzione \func{aio\_fsync}, che ha lo stesso effetto della
+analoga \func{fsync}, ma viene esguita in maniera asincrona; il suo prototipo
+è:
+\begin{prototype}{aio.h}
+{ssize\_t aio\_return(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},
+  \macro{EAGAIN}, \macro{EBADF} o \macro{EINVAL}.}
+\end{prototype}
+
+La funzione richiede la sincronizzazione delle operazioni di I/O, essendo la
+richiesta asincrona, 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 \macro{O\_DSYNC} le operazioni saranno completate con una chiamata a
+\func{fdatasync}, se si specifica \macro{O\_SYNC} con una chiamata a
+\func{fsync} (vedi \secref{sec:file_sync}).
+
+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.
+
+In alcuni casi può essere necessario interrompere le operazioni (in genere
+quando viene richiesta un'uscita immediata dal programam), per questo lo
+standard POSIX.1b prevede una funzioni apposita, \func{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}, setta \var{errno} al valore
+  \macro{EBADF}.}
+\end{prototype}
+
+La funzione permette di cancellare una operazione specifica sul file
+\param{fildes}, o tutte le operazioni pendenti, specificando \macro{NULL} come
+valore di \param{aiocbp}.  Quando una operazione viene cancellata
+\func{aio\_error} riporterà \macro{ECANCELED} come codice di errore, ed il suo
+codice di ritorno sarà -1, inoltre il meccanismo di notifica non verrà
+invocato.
+
+I possibili valori di ritorno di \func{aio\_cancel} sono tre:
+\macro{AIO\_ALLDONE} indica che le operazioni di cui si è richiesta la
+cancellazione sono state già completate, \macro{AIO\_CANCELED} indica che
+tutte le operazioni richieste sono state cancellate, e
+\macro{AIO\_NOTCANCELED} che alcune delle operazioni erano in corso e non sono
+state cancellate.  
+
+In quest'ultimo caso occorre chiamare \func{aio\_error} per determinare quali
+sono le operazioni cancellate. Le operazioni che non sono state cancellate
+proseguono il loro corso normale, compreso quanto relativo al meccanismo di
+notifica del loro avvenuto completamento.
+
+Benché l'I/O asincrono preveda un meccanismo di notifica, che permette di
+bloccare un processo in maniera relativamente semplice fino al completamento
+di una determinata operazione, lo standard fornisce anche una apposita
+funzione, \func{aio\_suspend}, che permette di sospendere l'esecuzione di un
+processo 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 errorem nel qual caso \var{errno} viene
+    settata ai valori:
+    \begin{errlist}
+    \item[\macro{EAGAIN}] Nessuna operazione è stata completata entro
+      \param{timeout}.
+    \item[\macro{ENOSYS}] La funzione non è implementata.
+    \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+    \end{errlist}
+  }
+\end{prototype}
+
+La funzione permette di bloccare il processo chiamante 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 con delle strutture \var{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 \macro{NULL} per \param{timout} comporta una attesa
+infinita.
+
+Lo standard infine ha previsto pure una funzione, \func{lio\_listio}, che
+permette di effettuare la richiesta di una intera lista di operazioni di
+lettura o scrittura; il suo prototipo è: 
+\begin{prototype}{aio.h}
+  {int lio\_listio(int mode, struct aiocb * const list[], int nent, struct
+    sigevent *sig)}
+  
+  Richiede l'esecuzione delle operazioni di I/O elencata da \param{list},
+  secondo la modalità \param{mode}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+    errorem nel qual caso \var{errno} viene settata ai valori:
+    \begin{errlist}
+    \item[\macro{EAGAIN}] Nessuna operazione è stata completata entro
+      \param{timeout}.
+    \item[\macro{ENOSYS}] La funzione non è implementata.
+    \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+    \end{errlist}
+  }
+\end{prototype}
+
+La funzione esegue la richiesta delle \param{nent} operazioni indicate dalla
+lista \param{list}; questa deve contenere gli indirizzi di altrettanti control
+block, opportunamente inizializzati; in particolare nel caso dovrà essere
+specificato il tipo di operazione tramite il campo \var{aio\_lio\_opcode}, che
+può prendere i tre valori:
+\begin{description*}
+\item[\macro{LIO\_READ}]  richiede una operazione di lettura.
+\item[\macro{LIO\_WRITE}] richiede una operazione di scrittura.
+\item[\macro{LIO\_NOP}] non effettua nessuna operazione.
+\end{description*}
+l'ultimo viene usato quando si ha a che fare con un vettore di dimensione
+fissa, per poter specificare solo alcune operazioni, o quando si è dovuto
+cancellare delle operazioni e si deve ripetere la richiesta per quelle non
+completate.
+
+L'argomento \param{mode} permette di stabilire il comportamento della
+funzione, se viene specificato il valore \macro{LIO\_WAIT} la funzione si
+blocca fino al completamento di tutte le operazioni richieste; se invece si
+spercifica \macro{LIO\_NOWAIT} la funzione ritorna immediatamente dopo aver
+messo in coda tutte le richieste. In questo caso il chiamante può richiedere
+una notifica del completamento di tutte le richieste settando \param{sig}. 
+
+
 
 
 \subsection{I/O multiplo}