\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct pollfd {
- int fd; /* file descriptor */
- short events; /* requested events */
- short revents; /* returned events */
-};
- \end{lstlisting}
+ \includestruct{listati/pollfd.h}
\end{minipage}
\normalsize
- \caption{La struttura \struct{pollfd}, utilizzata per specificare le modalità
- di controllo di un file descriptor alla funzione \func{poll}.}
+ \caption{La struttura \structd{pollfd}, utilizzata per specificare le
+ modalità di controllo di un file descriptor alla funzione \func{poll}.}
\label{fig:file_pollfd}
\end{figure}
di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
asincrono (effettuato a partire dal 2.5.32).} esiste una sola versione
stabile di questa interfaccia, quella delle \acr{glibc}, che è realizzata
-completamente in user space. Esistono comunque vari progetti sperimentali
-(come il KAIO della SGI, o i patch di Benjamin La Haise) che prevedono un
-supporto diretto da parte del kernel.
+completamente in user space, ed accessibile linkando i programmi con la
+libreria \file{librt}. Esistono comunque vari progetti sperimentali (come il
+KAIO della SGI, o i patch di Benjamin La Haise) che prevedono un supporto
+diretto da parte del kernel.
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
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct aiocb
-{
- int aio_fildes; /* File descriptor. */
- off_t aio_offset; /* File offset */
- int aio_lio_opcode; /* Operation to be performed. */
- int aio_reqprio; /* Request priority offset. */
- volatile void *aio_buf; /* Location of buffer. */
- size_t aio_nbytes; /* Length of transfer. */
- struct sigevent aio_sigevent; /* Signal number and value. */
-};
- \end{lstlisting}
+ \includestruct{listati/aiocb.h}
\end{minipage}
\normalsize
- \caption{La struttura \struct{aiocb}, usata per il controllo dell'I/O
+ \caption{La struttura \structd{aiocb}, usata per il controllo dell'I/O
asincrono.}
\label{fig:file_aiocb}
\end{figure}
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct sigevent
-{
- sigval_t sigev_value;
- int sigev_signo;
- int sigev_notify;
- sigev_notify_function;
- sigev_notify_attributes;
-};
- \end{lstlisting}
+ \includestruct{listati/sigevent.h}
\end{minipage}
\normalsize
- \caption{La struttura \struct{sigevent}, usata per specificare le modalità di
- notifica degli eventi relativi alle operazioni di I/O asincrono.}
+ \caption{La struttura \structd{sigevent}, usata per specificare le modalità
+ di notifica degli eventi relativi alle operazioni di I/O asincrono.}
\label{fig:file_sigevent}
\end{figure}
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[\const{SIGEV\_NONE}] Non viene inviata nessuna notifica.
+\item[\const{SIGEV\_NONE}] Non viene inviata nessuna notifica.
\item[\const{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
- chiamante il segnale specificato nel campo \var{sigev\_signo}, se il
- gestore è installato con \const{SA\_SIGINFO}, il gli verrà restituito
- il valore di \var{sigev\_value} in come valore del campo \var{si\_value} per
+ chiamante il segnale specificato da \var{sigev\_signo}; se il gestore di
+ questo è stato installato con \const{SA\_SIGINFO} gli verrà restituito il
+ valore di \var{sigev\_value} (la cui definizione è in
+ \figref{fig:sig_sigval}) come valore del campo \var{si\_value} di
\struct{siginfo\_t}.
\item[\const{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}.
+ thread che esegue la funzione specificata da \var{sigev\_notify\_function}
+ con argomento \var{sigev\_value}, e con gli attributi specificati da
+ \var{sigev\_notify\_attribute}.
\end{basedescript}
Le due funzioni base dell'interfaccia per l'I/O asincrono sono
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct iovec {
- __ptr_t iov_base; /* Starting address */
- size_t iov_len; /* Length in bytes */
-};
- \end{lstlisting}
+ \includestruct{listati/iovec.h}
\end{minipage}
\normalsize
- \caption{La struttura \struct{iovec}, usata dalle operazioni di I/O
+ \caption{La struttura \structd{iovec}, usata dalle operazioni di I/O
vettorizzato.}
\label{fig:file_iovec}
\end{figure}
potranno essere visibili o meno a seconda del momento in cui la memoria
virtuale trasporterà dal disco in memoria quella sezione del file, perciò è
del tutto imprevedibile il risultato della modifica di un file nei confronti
-del contenuto della memoria mappata su cui è mappato.
-
-Per quanto appena visto, è sempre sconsigliabile eseguire scritture su file
-attraverso l'interfaccia standard, quando lo si è mappato in memoria, è invece
-possibile usare l'interfaccia standard per leggere un file mappato in memoria,
-purché si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in
-memoria mette a disposizione la funzione \funcd{msync} per sincronizzare il
-contenuto della memoria mappata con il file su disco; il suo prototipo è:
+del contenuto della memoria su cui è mappato.
+
+Per questo, è sempre sconsigliabile eseguire scritture su file attraverso
+l'interfaccia standard, quando lo si è mappato in memoria, è invece possibile
+usare l'interfaccia standard per leggere un file mappato in memoria, purché si
+abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette
+a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della
+memoria mappata con il file su disco; il suo prototipo è:
\begin{functions}
\headdecl{unistd.h}
\headdecl{sys/mman.h}
\begin{figure}[!bht]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct flock {
- short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
- short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
- off_t l_start; /* Offset where the lock begins. */
- off_t l_len; /* Size of the locked area; zero means until EOF. */
- pid_t l_pid; /* Process holding the lock. */
-};
- \end{lstlisting}
+ \includestruct{listati/flock.h}
\end{minipage}
\normalsize
- \caption{La struttura \struct{flock}, usata da \func{fcntl} per il file
+ \caption{La struttura \structd{flock}, usata da \func{fcntl} per il file
locking.}
\label{fig:struct_flock}
\end{figure}
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
- int type = F_UNLCK; /* lock type: default to unlock (invalid) */
- off_t start = 0; /* start of the locked region: default to 0 */
- off_t len = 0; /* length of the locked region: default to 0 */
- int fd, res, i; /* internal variables */
- int bsd = 0; /* semantic type: default to POSIX */
- int cmd = F_SETLK; /* lock command: default to non-blocking */
- struct flock lock; /* file lock structure */
- ...
- if ((argc - optind) != 1) { /* There must be remaing parameters */
- printf("Wrong number of arguments %d\n", argc - optind);
- usage();
- }
- if (type == F_UNLCK) { /* There must be a -w or -r option set */
- printf("You should set a read or a write lock\n");
- usage();
- }
- fd = open(argv[optind], O_RDWR); /* open the file to be locked */
- if (fd < 0) { /* on error exit */
- perror("Wrong filename");
- exit(1);
- }
- /* do lock */
- if (bsd) { /* if BSD locking */
- /* rewrite cmd for suitables flock operation values */
- if (cmd == F_SETLKW) { /* if no-blocking */
- cmd = LOCK_NB; /* set the value for flock operation */
- } else { /* else */
- cmd = 0; /* default is null */
- }
- if (type == F_RDLCK) cmd |= LOCK_SH; /* set for shared lock */
- if (type == F_WRLCK) cmd |= LOCK_EX; /* set for exclusive lock */
- res = flock(fd, cmd); /* esecute lock */
- } else { /* if POSIX locking */
- /* setting flock structure */
- lock.l_type = type; /* set type: read or write */
- lock.l_whence = SEEK_SET; /* start from the beginning of the file */
- lock.l_start = start; /* set the start of the locked region */
- lock.l_len = len; /* set the length of the locked region */
- res = fcntl(fd, cmd, &lock); /* do lock */
- }
- /* check lock results */
- if (res) { /* on error exit */
- perror("Failed lock");
- exit(1);
- } else { /* else write message */
- printf("Lock acquired\n");
- }
- pause(); /* stop the process, use a signal to exit */
- return 0;
-}
- \end{lstlisting}
+ \includecodesample{listati/Flock.c}
\end{minipage}
\normalsize
\caption{Sezione principale del codice del programma \file{Flock.c}.}