La funzione mette il processo in stato di \textit{sleep} (vedi
\tabref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor
-degli insiemo specificati (\param{readfds}, \param{writefds} e
+degli insiemi specificati (\param{readfds}, \param{writefds} e
\param{exceptfds}), non diventa attivo, per un tempo massimo specificato da
\param{timeout}.
System V ha introdotto una sua interfaccia per gestire l'\textit{I/O
multiplexing}, basata sulla funzione \func{poll},\footnote{la funzione è
prevista dallo standard XPG4, ed è stata introdotta in Linux come system
- call a partire dal kernel 2.1.23 e dalle libc 5.4.28.} il cui prototipo è:
+ call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui prototipo è:
\begin{prototype}{sys/poll.h}
{int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
\type{pollfd}, la cui definizione è riportata in \figref{fig:file_pollfd}.
Come \func{select} anche \func{poll} permette di interrompere l'attesa dopo un
certo tempo, che va specificato attraverso \param{timeout} in numero di
-millesecondi (un valore negativo indica un'attesa indefinita).
+millisecondi (un valore negativo indica un'attesa indefinita).
\begin{figure}[!htb]
\footnotesize \centering
\macro{POLLOUT} & 0x004 & È possibile la scrittura immediata.\\
\hline
\macro{POLLERR} & 0x008 & C'è una condizione di errore.\\
- \macro{POLLHUP} & 0x010 & Si è vericato un hung-up.\\
+ \macro{POLLHUP} & 0x010 & Si è verificato un hung-up.\\
\macro{POLLNVAL} & 0x020 & Il file descriptor non è aperto.\\
\hline
\macro{POLLRDNORM}& 0x040 & Sono disponibili in lettura dati normali.\\
sostituisce i precedenti, ed aggiunge a \func{select} una nuova funzione
\func{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed
l'header \file{sys/select.h}, compaiono in Linux a partire dalle \acr{glibc}
- 2.0. Le \acr{libc4} e \acr{libc5} non contengono questo header, le
+ 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header, le
\acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
senza l'argomento \param{sigmask}, la definizione corretta è presente dalle
\acr{glibc} 2.1-2.2.1 se si è definito \macro{\_GNU\_SOURCE} e nelle
In questo modo si può evitare l'uso delle funzioni \func{poll} o \func{select}
che, quando vengono usate con un numero molto grande di file descriptor, non
hanno buone prestazioni. In tal caso infatti la maggior parte del loro tempo
-di esecuzione è impegato per eseguire uno scan su tutti i file descriptor
-tenuti sotto controllo per determinare quali sono quelli (in genere un piccola
-percentuale) che sono diventati attivi.
+di esecuzione è impegnato ad eseguire una scansione su tutti i file descriptor
+tenuti sotto controllo per determinare quali di essi (in genere una piccola
+percentuale) sono diventati attivi.
Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
presenta notevoli problemi, dato che non è possibile determinare, quando sono
(vedi \secref{sec:sig_real_time}) settando esplicitamente con il comando
\macro{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
I/O asincrono (il segnale di default è \macro{SIGIO}). In questo caso il
-manipolatorem tutte le volte che riceverà \macro{SI\_SIGIO} come valore del
+manipolatore tutte le volte che riceverà \macro{SI\_SIGIO} come valore del
campo \var{si\_code}\footnote{il valore resta \macro{SI\_SIGIO} qualunque sia
il segnale che si è associato all'I/O asincrono, ed indica appunto che il
segnale è stato generato a causa di attività nell'I/O asincrono.} di
si eccedono le dimensioni di quest'ultima; in tal caso infatti il kernel, non
potendo più assicurare il comportamento corretto per un segnale real-time,
invierà al suo posto un \var{SIGIO}, su cui si accumuleranno tutti i segnali
-in eccesso, e si dovra determinare al solito modo quali sono i file diventati
+in eccesso, e si dovrà determinare al solito modo quali sono i file diventati
attivi.
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} viene settata ai valori:
\begin{errlist}
+ \item[\macro{EINTR}] La funzione è stata interrotta.
\item[\macro{EINVAL}] Si è specificato un valore non valido per
\param{set}.
\end{errlist}
ed inoltre \macro{EFAULT}.}
\end{prototype}
-
-Altre due funzioni, usate prevalentemente con i thread, sono
-\func{sigwaitinfo} e \func{sigtimedwait}, i loro prototipi sono:
+La funzione estrae dall'insieme dei segnali pendenti uno qualunque dei segnali
+specificati da \param{set}, il cui valore viene restituito in \param{sig}. Se
+sono pendenti più segnali, viene estratto quello a priorità più alta (cioè con
+il numero più basso). Se, nel caso di segnali real-time, c'è più di un segnale
+pendente, ne verrà estratto solo uno. Una volta estratto il segnale non verrà
+più consegnato, e se era in una coda il suo posto sarà liberato. Se non c'è
+nessun segnale pendente il processo viene bloccato fintanto che non ne arriva
+uno.
+
+Per un funzionamento corretto la funzione richiede che alla sua chiamata i
+segnali di \param{set} siano bloccati. In caso contrario si avrebbe un
+conflitto con gli eventuali manipolatori: pertanto non si deve utilizzare per
+lo stesso segnale questa funzione e \func{sigaction}. Se questo non avviene il
+comportamento del sistema è indeterminato: il segnale può sia essere
+consegnato che essere ricevuto da \func{sigwait}, il tutto in maniera non
+prevedibile.
+
+Lo standard POSIX.1b definisce altre due funzioni, anch'esse usate
+prevalentemente con i thread; \func{sigwaitinfo} e \func{sigtimedwait}, i
+relativi prototipi sono:
\begin{functions}
\headdecl{signal.h}
\funcdecl{int sigwaitinfo(const sigset\_t *set, siginfo\_t *info)}
-
- Attende che uno dei segnali specificati in \param{set} sia pendente.
- \funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *info, const
- struct timespec *timeout)}
-
- Attende che uno dei segnali specificati in \param{set} sia pendente.
-
+ Analoga a \func{sigwait}, ma riceve anche le informazioni associate al
+ segnale in \param{info}.
+
+ \funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *value, const
+ struct timespec *info)}
+
+ Analoga a \func{sigwaitinfo}, con un la possibilità di specificare un
+ timeout in \param{timeout}.
- \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} viene settata ai valori:
+
+ \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} viene settata ai valori già visti per
+ \func{sigwait}, ai quali se aggiunge, per \func{sigtimedwait}:
\begin{errlist}
- \item[\macro{EINVAL}] Si è specificato un valore non valido per
- \item[\macro{EAGAIN}] La coda è esarita, ci sono già \macro{SIGQUEUE\_MAX}
- segnali in attesa si consegna.
- \item[\macro{EINTR}] Non si hanno privilegi appropriati per inviare il
- segnale al processo specificato.
- \item[\macro{ENOSYS}] Il processo \param{pid} non esiste.
+ \item[\macro{EAGAIN}] Si è superato il timeout senza che un segnale atteso
+ fosse emmesso.
\end{errlist}
- ed inoltre \macro{EFAULT}.}
+}
\end{functions}
-
-
-
+Entrambe le funzioni sono estensioni di \func{sigwait}. La prima permette di
+ricevere, oltre al numero del segnale, anche le informazioni ad esso associate
+tramite \param{info}; in particolare viene restituito il numero del segnale
+nel campo \var{si\_signo}, la sua causa in \var{si\_code}, e se il segnale è
+stato immesso sulla coda con \func{sigqueue}, il valore di ritorno ad esso
+associato viene riportato in \var{si\_value}, che altrimenti è indefinito.
+
+La seconda è identica alla prima ma in più permette di specificare un timeout,
+scaduto il quale ritornerà con un errore. Se si specifica un puntatore nullo
+il comportamento sarà identico a \func{sigwaitinfo}, se si specifica un tempo
+di timeout nullo, e non ci sono sengali pendenti la funzione ritornerà
+immediatamente; in questo modo si può eliminare un segnale dalla coda senza
+dover essere bloccati qualora esso non sia presente.
+
+
+L'uso di queste funzioni è principalmente associato alla gestione dei segnali
+com i thread. In genere esse vengono chiamate dal thread incaricato della
+gestione, che al ritorno della funzione esegue il codice che usualmente
+sarebbe messo nel manipolatore, per poi ripetere la chiamata per mettersi in
+attesa del segnale successivo. Questo ovviamente comporta che non devono
+essere installati manipolatori, che solo il thread di gestione deve usare
+\func{sigwait} e che, per evitare che venga eseguita l'azione di default, i
+segnali gestiti in questa maniera devono essere mascherati per tutti i thread,
+compreso quello dedicato alla gestione, che potrebbe riceverlo fra due
+chiamate successive.
%%% Local Variables:
%%% mode: latex