Aggiunte varie sempre sui segnali real-time
[gapil.git] / signal.tex
index f0565a23a2e305ccbfbe3fa04130cad36872efa8..ea8454e2555c90322f0e83db3d7db492d783e634 100644 (file)
@@ -16,7 +16,7 @@ In questo capitolo esamineremo i vari aspetti della gestione dei segnali,
 partendo da una introduzione relativa ai concetti base con cui essi vengono
 realizzati, per poi affrontarne la classificazione a secondo di uso e modalità
 di generazione fino ad esaminare in dettaglio funzioni e le metodologie di
-gestione.
+gestione. 
 
 
 \section{Introduzione}
@@ -120,8 +120,8 @@ int sig_handler()
 Questa è la ragione per cui l'implementazione dei segnali secondo questa
 semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
 segnale e la reinstallazione del suo manipolatore non sono operazioni
-atomiche, e sono sempre possibili delle race condition (sull'argomento vedi
-quanto detto in \secref{sec:proc_multi_prog}).
+atomiche, e sono sempre possibili delle race condition\index{race condition}
+(sull'argomento vedi quanto detto in \secref{sec:proc_multi_prog}).
 
 Un'altro problema è che in questa semantica non esiste un modo per bloccare i
 segnali quando non si vuole che arrivino; i processi possono ignorare il
@@ -242,7 +242,8 @@ Un programma pu
 \secref{sec:sig_sigaction}). Se si è installato un manipolatore sarà
 quest'ultimo ad essere eseguito alla notifica del segnale.  Inoltre il sistema
 farà si che mentre viene eseguito il manipolatore di un segnale, quest'ultimo
-venga automaticamente bloccato (così si possono evitare race condition).
+venga automaticamente bloccato (così si possono evitare race
+condition\index{race condition}).
 
 Nel caso non sia stata specificata un'azione, viene utilizzata l'azione
 standard che (come vedremo in \secref{sec:sig_standard}) è propria di ciascun
@@ -411,9 +412,9 @@ tipologia, verr
 \label{sec:sig_prog_error}
 
 Questi segnali sono generati quando il sistema, o in certi casi direttamente
-l'hardware (come per i page fault non validi) rileva un qualche errore
-insanabile nel programma in esecuzione. In generale la generazione di questi
-segnali significa che il programma ha dei gravi problemi (ad esempio ha
+l'hardware (come per i \textit{page fault} non validi) rileva un qualche
+errore insanabile nel programma in esecuzione. In generale la generazione di
+questi segnali significa che il programma ha dei gravi problemi (ad esempio ha
 dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica
 proibita) e l'esecuzione non può essere proseguita.
 
@@ -662,11 +663,11 @@ segnali sono:
   situazione precedente.
 \item[\macro{SIGXCPU}] Sta per \textit{CPU time limit exceeded}. Questo
   segnale è generato quando un processo eccede il limite impostato per il
-  tempo di CPU disponibile, vedi \secref{sec:sys_xxx}. 
+  tempo di CPU disponibile, vedi \secref{sec:sys_resource_limit}. 
 \item[\macro{SIGXFSZ}] Sta per \textit{File size limit exceeded}. Questo
   segnale è generato quando un processo tenta di estendere un file oltre le
   dimensioni specificate dal limite impostato per le dimensioni massime di un
-  file, vedi \secref{sec:sys_xxx}. 
+  file, vedi \secref{sec:sys_resource_limit}. 
 \end{basedescript}
 
 
@@ -714,7 +715,7 @@ di \func{strsignal}. Nel caso si debba mantenere traccia del messaggio sar
 necessario copiarlo.
 
 La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror}
-descritta in \secref{sec:sys_strerror}; il suo prototipo è:
+descritta sempre in \secref{sec:sys_strerror}; il suo prototipo è:
 \begin{prototype}{signal.h}{void psignal(int sig, const char *s)} 
   Stampa sullo standard error un messaggio costituito dalla stringa \param{s},
   seguita da due punti ed una descrizione del segnale indicato da \param{sig}.
@@ -750,7 +751,7 @@ processo alla loro occorrenza.
 
 
 \subsection{Il comportamento generale del sistema.}
-  \label{sec:sig_gen_beha}
+\label{sec:sig_gen_beha}
 
 Abbiamo già trattato in \secref{sec:sig_intro} le modalità con cui il sistema
 gestisce l'interazione fra segnali e processi, ci resta da esaminare però il
@@ -778,28 +779,29 @@ manipolatore; viene mantenuto invece ogni eventuale settaggio dell'azione a
 programmi eseguiti in background, che altrimenti sarebbero interrotti da una
 successiva pressione di \texttt{C-c} o \texttt{C-y}.
 
-Per quanto riguarda tutte le altre system call esse vengono tradizionalmente
-classificate, proprio in base al loro comportamento nei confronti dei segnali,
-in \textsl{lente} (\textit{slow}) e \textsl{veloci} (\textit{fast}). La gran
-parte appartiene a quest'ultima categoria che non è influenzata dall'arrivo di
-un segnale. In tal caso un eventuale manipolatore viene sempre eseguito dopo
-che la system call è stata completata. Esse sono dette \textsl{veloci} proprio
-in quanto la loro esecuzione è sostanzialmente immediata e attendere per
-eseguire un manipolatore non comporta nessun inconveniente.
-
-Esistono però dei casi in cui questo non è possibile perché renderebbe
-impossibile una risposta pronta al segnale. In generale questo avviene tutte
-le volte che si ha a che fare con system call che possono bloccarsi
-indefinitamente, (quelle che, per questo, vengono chiamate \textsl{lente}). Un
-elenco dei casi in cui si presenta questa situazione è il seguente:
+Per quanto riguarda il comportamento di tutte le altre system call si danno
+sostanzialmente due casi, a seconda che esse siano \textsl{lente}
+(\textit{slow}) o \textsl{veloci} (\textit{fast}). La gran parte di esse
+appartiene a quest'ultima categoria, che non è influenzata dall'arrivo di un
+segnale. Esse sono dette \textsl{veloci} in quanto la loro esecuzione è
+sostanzialmente immediata; la risposta al segnale viene sempre data dopo che
+la system call è stata completata, in quanto attendere per eseguire un
+manipolatore non comporta nessun inconveniente.
+
+In alcuni casi però alcune system call (che per questo motivo vengono chiamate
+\textsl{lente}) possono bloccarsi indefinitamente. In questo caso non si può
+attendere la conclusione della sistem call, perché questo renderebbe
+impossibile una risposta pronta al segnale, per cui il manipolatore viene
+eseguito prima che la system call sia ritornata.  Un elenco dei casi in cui si
+presenta questa situazione è il seguente:
 \begin{itemize}
-\item lettura da file che possono bloccarsi in attesa di dati non ancora
-  presenti (come per certi file di dispositivo, la rete o le pipe).
-\item scrittura sugli stessi file, nel caso in cui dati non possano essere
+\item la lettura da file che possono bloccarsi in attesa di dati non ancora
+  presenti (come per certi file di dispositivo, i socket o le pipe).
+\item la scrittura sugli stessi file, nel caso in cui dati non possano essere
   accettati immediatamente.
-\item apertura di un file di dispositivo che richiede operazioni non immediate
-  per una una risposta. 
-\item operazioni eseguite con \func{ioctl} che non è detto possano essere
+\item l'apertura di un file di dispositivo che richiede operazioni non
+  immediate per una una risposta.
+\item le operazioni eseguite con \func{ioctl} che non è detto possano essere
   eseguite immediatamente.
 \item le funzioni di intercomunicazione che si bloccano in attesa di risposte
   da altri processi.
@@ -1120,7 +1122,7 @@ illustrati in precedenza usare; i possibili valori sono riportati in
 Il valore della struttura specificata \param{value} viene usato per settare il
 timer, se il puntatore \param{ovalue} non è nullo il precedente valore viene
 salvato qui. I valori dei timer devono essere indicati attraverso una
-struttura \var{itimerval}, definita in \figref{fig:file_stat_struct}.
+struttura \type{itimerval}, definita in \figref{fig:file_stat_struct}.
 
 La struttura è composta da due membri, il primo, \var{it\_interval} definisce
 il periodo del timer; il secondo, \var{it\_value} il tempo mancante alla
@@ -1141,16 +1143,10 @@ struct itimerval
     struct timeval it_interval; /* next value */
     struct timeval it_value;    /* current value */
 };
-
-struct timeval 
-{
-    long tv_sec;                /* seconds */
-    long tv_usec;               /* microseconds */
-};
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \var{itimerval}, che definisce i valori dei timer di
+  \caption{La struttura \type{itimerval}, che definisce i valori dei timer di
     sistema.} 
   \label{fig:sig_itimerval}
 \end{figure}
@@ -1336,9 +1332,9 @@ Lo standard richiede che la funzione sia implementata in maniera del tutto
 indipendente da \func{alarm}\footnote{nel caso di Linux questo è fatto
   utilizzando direttamente il timer del kernel.} e sia utilizzabile senza
 interferenze con l'uso di \macro{SIGALRM}. La funzione prende come parametri
-delle strutture di tipo \var{timespec}, la cui definizione è riportata in 
-\figref{fig:sig_timespec_def}, che permettono di specificare un tempo con una
-precisione (teorica) fino al nanosecondo. 
+delle strutture di tipo \var{timespec}, la cui definizione è riportata in
+\figref{fig:sys_timeval_struct}, che permettono di specificare un tempo con
+una precisione (teorica) fino al nanosecondo.
 
 La funzione risolve anche il problema di proseguire l'attesa dopo
 l'interruzione dovuta ad un segnale; infatti in tal caso in \param{rem} viene
@@ -1355,21 +1351,6 @@ sia scarico ed il processa venga immediatamente rimesso in esecuzione); per
 questo motivo il valore restituito in \param{rem} è sempre arrotondato al
 multiplo successivo di 1/\macro{HZ}.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct timespec {
-    time_t  tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
-};
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \var{timespec} di \func{nanosleep}.} 
-  \label{fig:sig_timespec_def}
-\end{figure}
-
 In realtà è possibile ottenere anche pause più precise del centesimo di
 secondo usando politiche di scheduling real time come \macro{SCHED\_FIFO} o
 \macro{SCHED\_RR}; in tal caso infatti il meccanismo di scheduling ordinario
@@ -1421,7 +1402,7 @@ la creazione di zombie.
 #include <sys/wait.h>
 #include "macro.h"
 
-void Hand_CHLD(int sig)
+void sigchld_hand(int sig)
 {
     int errno_save;
     int status;
@@ -1492,8 +1473,9 @@ tutti gli stati di terminazione sono stati ricevuti.
 
 Le funzioni esaminate finora fanno riferimento ad alle modalità più elementari
 della gestione dei segnali; non si sono pertanto ancora prese in
-considerazione le tematiche più complesse, collegate alle varie race condition
-che i segnali possono generare e alla natura asincrona degli stessi.
+considerazione le tematiche più complesse, collegate alle varie race
+condition\index{race condition} che i segnali possono generare e alla natura
+asincrona degli stessi.
 
 Affronteremo queste problematiche in questa sezione, partendo da un esempio
 che le evidenzi, per poi prendere in esame le varie funzioni che permettono di
@@ -1560,13 +1542,13 @@ unsigned int sleep(unsigned int seconds)
 
 Questo codice però, a parte il non gestire il caso in cui si è avuta una
 precedente chiamata a \func{alarm} (che si è tralasciato per brevità),
-presenta una pericolosa race condition.  Infatti se il processo viene
-interrotto fra la chiamata di \func{alarm} e \func{pause} può capitare (ad
-esempio se il sistema è molto carico) che il tempo di attesa scada prima
-dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo l'arrivo di
-\macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un deadlock, in
-quanto \func{pause} non verrebbe mai più interrotta (se non in caso di un
-altro segnale).
+presenta una pericolosa race condition\index{race condition}.  Infatti se il
+processo viene interrotto fra la chiamata di \func{alarm} e \func{pause} può
+capitare (ad esempio se il sistema è molto carico) che il tempo di attesa
+scada prima dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo
+l'arrivo di \macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un
+deadlock, in quanto \func{pause} non verrebbe mai più interrotta (se non in
+caso di un altro segnale).
 
 Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
 SVr2) usando la funzione \func{longjmp} (vedi \secref{sec:proc_longjmp}) per
@@ -1670,10 +1652,10 @@ quale potr
 segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
 
 Questo è il tipico esempio di caso, già citato in \secref{sec:proc_race_cond},
-in cui si genera una race condition; se infatti il segnale arriva
-immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima
-della cancellazione del flag (\texttt{\small 7}), la sua occorrenza sarà
-perduta.
+in cui si genera una race condition\index{race condition}; se infatti il
+segnale arriva immediatamente dopo l'esecuzione del controllo (\texttt{\small
+  6}) ma prima della cancellazione del flag (\texttt{\small 7}), la sua
+occorrenza sarà perduta.
 
 Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
 funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
@@ -1815,16 +1797,6 @@ struct sigaction
   \label{fig:sig_sigaction}
 \end{figure}
 
-Come si può notare da quanto riportato in \figref{fig:sig_sigaction} in Linux
-\func{sigaction} permette di specificare il manipolatore in due forme diverse,
-indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere
-usate in maniera alternativa (in certe implementazioni questi vengono
-specificati come \ctyp{union}): la prima è quella classica usata anche con
-\func{signal}, la seconda permette invece di usare un manipolatore in grado di
-ricevere informazioni più dettagliate dal sistema (ad esempio il tipo di
-errore in caso di \macro{SIGFPE}), attraverso dei parametri aggiuntivi; per i
-dettagli si consulti la man page di \func{sigaction}).
-
 Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
 essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque
 sempre aggiunto il segnale che ne ha causato la chiamata, a meno che non si
@@ -1881,6 +1853,81 @@ in \tabref{tab:sig_sa_flag}.
   \label{tab:sig_sa_flag}
 \end{table}
 
+Come si può notare in \figref{fig:sig_sigaction} \func{sigaction}
+permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ed è
+  stata aggiunta nei kernel della serie 2.1.x con l'introduzione dei segnali
+  real-time (vedi \secref{sec:sig_real_time}). In precedenza era possibile
+  ottenere alcune informazioni addizionali usando \var{sa\_handler} con un
+  secondo parametro addizionale di tipo \var{struct sigcontext}, che adesso è
+  deprecato.}  di utilizzare due forme diverse di manipolatore, da
+specificare, a seconda dell'uso o meno del flag \macro{SA\_SIGINFO},
+rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler},
+(che devono essere usati in maniera alternativa, in certe implementazioni
+questi vengono addirittura definiti come \ctyp{union}): la prima è quella
+classica usata anche con \func{signal}, la seconda permette invece di usare un
+manipolatore in grado di ricevere informazioni più dettagliate dal sistema,
+attraverso la struttura \type{siginfo\_t}, riportata in
+\figref{fig:sig_siginfo_t}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+siginfo_t {
+    int      si_signo;  /* Signal number */
+    int      si_errno;  /* An errno value */
+    int      si_code;   /* Signal code */
+    pid_t    si_pid;    /* Sending process ID */
+    uid_t    si_uid;    /* Real user ID of sending process */
+    int      si_status; /* Exit value or signal */
+    clock_t  si_utime;  /* User time consumed */
+    clock_t  si_stime;  /* System time consumed */
+    sigval_t si_value;  /* Signal value */
+    int      si_int;    /* POSIX.1b signal */
+    void *   si_ptr;    /* POSIX.1b signal */
+    void *   si_addr;   /* Memory location which caused fault */
+    int      si_band;   /* Band event */
+    int      si_fd;     /* File descriptor */
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \type{siginfo\_t}.} 
+  \label{fig:sig_siginfo_t}
+\end{figure}
+Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora
+possibile accedere alle informazioni restituite attraverso il puntatore a
+questa struttura. Tutti i segnali settano i campi \var{si\_signo}, che riporta
+il numero del segnale ricevuto, \var{si\_errno}, che riporta, quando diverso
+da zero, il codice dell'errore associato al segnale, e \var{si\_code}, che
+viene usato dal kernel per specificare maggiori dettagli riguardo l'evento che
+ha causato l'emissione del segnale.
+
+In generale \var{si\_code} contiene, per i segnali generici, per quelli
+real-time e per tutti quelli inviati tramite \func{kill}, informazioni circa
+l'origine del segnale (se generato dal kernel, da un timer, da \func{kill},
+ecc.). Alcuni segnali però usano \var{si\_code} per fornire una informazione
+specifica: ad esempio i vari segnali di errore (\macro{SIGFPE},
+\macro{SIGILL}, \macro{SIGBUS} e \macro{SIGSEGV}) lo usano per fornire
+maggiori dettagli riguardo l'errore (come il tipo di errore aritmetico, di
+istruzione illecita o di violazione di memoria) mentre alcuni segnali di
+controllo (\macro{SIGCHLD}, \macro{SIGTRAP} e \macro{SIGPOLL}) forniscono
+altre informazioni speecifiche.  In tutti i casi il valore del campo è
+riportato attraverso delle costanti (le cui definizioni si trovano
+\file{bits/siginfo.h}) il cui elenco dettagliato è disponibile nella man page
+di \func{sigaction}.
+
+Il resto della struttura è definito come \ctyp{union} ed i valori
+eventualmente presenti dipendono dal segnale, così \macro{SIGCHLD} ed i
+segnali real-time (vedi \secref{sec:sig_real_time}) inviati tramite
+\func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi valori corrispondenti
+al processo che ha emesso il segnale, \macro{SIGILL}, \macro{SIGFPE},
+\macro{SIGSEGV} e \macro{SIGBUS} avvalorano \var{si\_addr} con l'indirizzo cui
+è avvenuto l'errore, \macro{SIGIO} (vedi \secref{sec:file_asyncronous_io})
+avvalora \var{si\_fd} con il numero del file descriptor e \var{si\_band} per i
+dati urgenti su un socket.
+
 Benché sia possibile usare nello stesso programma sia \func{sigaction} che
 \func{signal} occorre molta attenzione, in quanto le due funzioni possono
 interagire in maniera anomala. Infatti l'azione specificata con
@@ -1894,16 +1941,9 @@ Per questo 
 ripristinare correttamente un manipolatore precedente, anche se questo è stato
 installato con \func{signal}. In generale poi non è il caso di usare il valore
 di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato
-che in certi sistemi questi possono essere diversi. In generale dunque, a meno
-che non si sia vincolati allo standard ISO C, è sempre il caso di evitare
-l'uso di \func{signal} a favore di \func{sigaction}.
-
-Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
-che abbia le stesse caratteristiche di \func{signal}, a definire una funzione
-equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si
-trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti
-allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso
-in seguito. 
+che in certi sistemi questi possono essere diversi. In definitiva dunque, a
+meno che non si sia vincolati all'aderenza stretta allo standard ISO C, è
+sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1935,6 +1975,13 @@ inline SigFunc * Signal(int signo, SigFunc *func)
   \label{fig:sig_Signal_code}
 \end{figure}
 
+Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
+che abbia le stesse caratteristiche di \func{signal}, a definire una funzione
+equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si
+trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti
+allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso
+in seguito. 
+
 \subsection{La gestione della \textsl{maschera dei segnali} o 
   \textit{signal mask}}
 \label{sec:sig_sigmask}
@@ -2016,15 +2063,15 @@ occorre ricordare che qualunque modifica alla maschera dei segnali viene
 perduta alla conclusione del terminatore. 
 
 Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte
-dei casi di race condition restano aperte alcune possibilità legate all'uso di
-\func{pause}; il caso è simile a quello del problema illustrato nell'esempio
-di \secref{fig:sig_sleep_incomplete}, e cioè la possibilità che il processo
-riceva il segnale che si intende usare per uscire dallo stato di attesa
-invocato con \func{pause} immediatamente prima dell'esecuzione di
-quest'ultima. Per poter effettuare atomicamente la modifica della maschera dei
-segnali (di solito attivandone uno specifico) insieme alla sospensione del
-processo lo standard POSIX ha previsto la funzione \func{sigsuspend}, il cui
-prototipo è:
+dei casi di race condition\index{race condition} restano aperte alcune
+possibilità legate all'uso di \func{pause}; il caso è simile a quello del
+problema illustrato nell'esempio di \secref{fig:sig_sleep_incomplete}, e cioè
+la possibilità che il processo riceva il segnale che si intende usare per
+uscire dallo stato di attesa invocato con \func{pause} immediatamente prima
+dell'esecuzione di quest'ultima. Per poter effettuare atomicamente la modifica
+della maschera dei segnali (di solito attivandone uno specifico) insieme alla
+sospensione del processo lo standard POSIX ha previsto la funzione
+\func{sigsuspend}, il cui prototipo è:
 \begin{prototype}{signal.h}
 {int sigsuspend(const sigset\_t *mask)} 
   
@@ -2052,14 +2099,9 @@ presenta neanche questa necessit
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
-#include <unistd.h>      /* unix standard library */
-#include <signal.h>      /* POSIX signal library */
 void alarm_hand(int);
 unsigned int sleep(unsigned int seconds)
 {
-/* 
- * Variables definition  
- */
     struct sigaction new_action, old_action;
     sigset_t old_mask, stop_mask, sleep_mask;
     /* set the signal handler */
@@ -2083,9 +2125,6 @@ unsigned int sleep(unsigned int seconds)
     /* return remaining time */
     return alarm(0);
 }
-/*
- * Signal Handler for SIGALRM
- */
 void alarm_hand(int sig) 
 {
     return;     /* just return to interrupt sigsuspend */
@@ -2114,18 +2153,18 @@ fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali
 \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
 \func{sigsuspend}.  
 
-In questo modo non sono più possibili race condition dato che \macro{SIGALRM}
-viene disabilitato con \func{sigprocmask} fino alla chiamata di
-\func{sigsuspend}. Questo metodo è assolutamente generale e può essere
-applicato a qualunque altra situazione in cui si deve attendere per un
+In questo modo non sono più possibili race condition\index{race condition}
+dato che \macro{SIGALRM} viene disabilitato con \func{sigprocmask} fino alla
+chiamata di \func{sigsuspend}. Questo metodo è assolutamente generale e può
+essere applicato a qualunque altra situazione in cui si deve attendere per un
 segnale, i passi sono sempre i seguenti:
-\begin{enumerate}
+\begin{enumerate*}
 \item Leggere la maschera dei segnali corrente e bloccare il segnale voluto
   con \func{sigprocmask}. 
 \item Mandare il processo in attesa con \func{sigsuspend} abilitando la
   ricezione del segnale voluto.
 \item Ripristinare la maschera dei segnali originaria.
-\end{enumerate}
+\end{enumerate*}
 Per quanto possa sembrare strano bloccare la ricezione di un segnale per poi
 riabilitarla immediatamente dopo, in questo modo si evita il deadlock dovuto
 all'arrivo del segnale prima dell'esecuzione di \func{sigsuspend}.
@@ -2161,7 +2200,7 @@ sistema un altro stack (invece di quello relativo al processo, vedi
 \secref{sec:proc_mem_layout}) solo durante l'esecuzione di un
 manipolatore. L'uso di uno stack alternativo è del tutto trasparente ai
 manipolatori, occorre però seguire una certa procedura:
-\begin{enumerate}
+\begin{enumerate*}
 \item Allocare un'area di memoria di dimensione sufficiente da usare come
   stack alternativo.
 \item Usare la funzione \func{sigaltstack} per rendere noto al sistema
@@ -2170,7 +2209,7 @@ manipolatori, occorre per
   specificando il flag \macro{SA\_ONSTACK} (vedi \tabref{tab:sig_sa_flag}) per
   dire al sistema di usare lo stack alternativo durante l'esecuzione del
   manipolatore. 
-\end{enumerate}
+\end{enumerate*}
 
 In genere il primo passo viene effettuato allocando un'opportuna area di
 memoria con \code{malloc}; in \file{signal.h} sono definite due costanti,
@@ -2299,25 +2338,139 @@ ripristinata in un successivo \func{siglongjmp}; quest'ultima funzione, a
 parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
 \func{longjmp}.
 
-\begin{prototype}{signal.h}
-{int sigaltstack(const stack\_t *ss, stack\_t *oss)}
+
+
+\subsection{I segnali real-time}
+\label{sec:sig_real_time}
+
+
+Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi
+real-time, ha introdotto una estensione del modello classico dei segnali che
+presenta dei significativi miglioramenti,\footnote{questa estensione è stata
+  introdotta in Linux a partire dal kernel 2.1.43(?), e dalle \acr{glibc}
+  2.1(?).} in particolare sono stati superati tre limiti fondamentali dei
+segnali classici:
+\begin{description}
+\item[I segnali non sono accumulati] 
   
-Installa un nuovo stack per i segnali.
+  se più segnali vengono generati prima dell'esecuzione di un manipolatore
+  questo sarà eseguito una sola volta, ed il processo non sarà in grado di
+  accorgersi di quante volte l'evento che ha generato il segnale è accaduto.
+\item[I segnali non trasportano informazione] 
   
-  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, nel qual caso \var{errno} assumerà i valori:
+  i segnali classici non prevedono prevedono altra informazione sull'evento
+  che li ha generati se non il fatto che sono stati emessi (tutta
+  l'informazione che il kernel associa ad un segnale è il suo numero).
+\item[I segnali non hanno un ordine di consegna] 
+
+  l'ordine in cui diversi segnali vengono consegnati è casuale e non
+  prevedibile. Non è possibile stabilire una priorità per cui la reazione a
+  certi segnali ha la precedenza rispetto ad altri.
+\end{description}
+
+
+Per poter superare queste limitazioni lo standard ha introdotto delle nuove
+caratteristiche, che sono state associate ad una nuova classe di segnali, che
+vengono chiamati \textsl{segnali real-time}, in particolare:
+
+\begin{itemize*}
+\item i segnali sono inseriti in una coda che permette di consegnare istanze
+  multiple dello stesso segnale qualora esso venga inviato più volte prima
+  dell'esecuzione del manipolatore; si assicura così che il processo riceva un
+  segnale per ogni occorrenza dell'evento che lo genera.
+\item è stata introdotta una priorità nella consegna dei segnali: i segnali
+  vengono consegnati in ordine a seconda del loro valore, partendo da quelli
+  con un numero minore, che pertanto hanno una priorità maggiore.
+\item è stata introdotta la possibilità di restituire dei dati al
+  manipolatore, attraverso l'uso di un campo apposito nella struttura
+  \type{siginfo\_t} accessibile tramite manipolatori di tipo
+  \var{sa\_sigaction}.
+\end{itemize*}
+
+Queste nuove caratteristiche (eccetto l'ultima, che, come visto in
+\secref{sec:sig_sigaction}, è parzialmente disponibile anche con i segnali
+ordinari) si applicano solo ai nuovi segnali real-time; questi ultimi sono
+accessibili in un range di valori specificati dalle due macro \macro{SIGRTMIN}
+e \macro{SIGRTMAX},\footnote{in Linux di solito il primo valore è 32, ed il
+  secondo \code{\_NSIG-1}, che di norma è 63, per un totale di 32 segnali
+  disponibili, contro gli almeno 8 richiesti da POSIX.1b.} che specificano il
+numero minimo e massimo associato ad un segnale real-time.
+
+I segnali con un numero più basso hanno una priorità maggiore e vengono
+consegnati per primi, inoltre i segnali real-time non possono interrompere
+l'esecuzione di un manipolatore di un segnale a priorità più alta; la loro
+azione di default è quella di terminare il programma.  I segnali ordinari
+hanno tutti la stessa priorità, che è più alta di quella di qualunque segnale
+real-time.
+
+Si tenga presente che questi nuovi segnali non sono associati a nessun evento
+sepcifico (a meno di non utilizzarli, come vedremo in
+\secref{sec:file_asyncronous_io}, per l'I/O asincrono) e devono essere inviati
+esplicitamente. Tutti i segnali real-time restituiscono al manipolatore, oltre
+ai campi \var{si\_pid} e \var{si\_uid} di \type{siginfo\_t} una struttura
+\type{sigval} (riportata in \figref{fig:sig_sigval}) in cui può essere
+restituito al processo un valore o un indirizzo, che costituisce il meccanismo
+con cui il segnale è in grado di inviare una ulteriore informazione al
+processo.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+union sigval {
+        int sival_int;
+        void *sival_ptr;
+}
+          \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \type{sigval}, usata dai segnali real time per
+    restituire dati al manipolatore.}
+  \label{fig:sig_sigval}
+\end{figure}
 
+A causa di queste loro caratteristiche, la funzione \func{kill} non è adatta
+ad inviare un segnale real time, in quanto non è in grado di fornire alcun
+valore per \var{sigval}; per questo motivo lo standard ha previsto una nuova
+funzione, \func{sigqueue}, il cui prototipo è:
+\begin{prototype}{signal.h}
+  {int sigqueue(pid\_t pid, int signo, const union sigval value)}
+  
+  Invia il segnale \param{signo} al processo \param{pid}, restituendo al
+  manipolatore il valore \param{value}.
+  
+  \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{ENOMEM}] La dimensione specificata per il nuovo stack è minore
-  di \macro{MINSIGSTKSZ}.
-  \item[\macro{EPERM}] Uno degli indirizzi non è valido.
-  \item[\macro{EFAULT}] Si è cercato di cambiare lo stack alternativo mentre
-  questo è attivo (cioè il processo è in esecuzione su di esso).
-  \item[\macro{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
-  valore diverso da zero che non è \macro{SS\_DISABLE}.
-  \end{errlist}}
+  \item[\macro{EAGAIN}] La coda è esarita, ci sono già \macro{SIGQUEUE\_MAX}
+    segnali in attesa si consegna.
+  \item[\macro{EPERM}] Non si hanno privilegi appropriati per inviare il
+    segnale al processo specificato.
+  \item[\macro{ESRCH}] Il processo \param{pid} non esiste.
+  \item[\macro{EINVAL}] Si è specificato un valore non valido per
+    \param{signo}.
+  \end{errlist}
+  ed inoltre \macro{ENOMEM}.}
 \end{prototype}
 
+Il comportamento della funzione è analogo a quello di \func{kill}, ed i
+privilegi occorrenti ad inviare il segnale ad un determinato processo sono gli
+stessi; un valore nullo di \func{signo} permette di verificare le condizioni
+di errore senza inviare nessun segnale.
+
+Se il segnale è bloccato la funzione ritorna immediatamente, se si è
+installato un manipolatore con \macro{SA\_SIGINFO} e ci sono risorse
+disponibili, vale a dire che c'è posto nella coda\footnote{la profondità della
+  coda è indicata dalla costante \macro{SIGQUEUE\_MAX}, una della tante
+  costanti di sistema definite dallo standard POSIX, che non abbiamo riportato
+  esplicitamente in \secref{sec:sys_limits}. Il suo valore minimo secondo lo
+  standard, \macro{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32.}, esso viene inserito
+e diventa pendente; una volta consegnato riporterà nel campo \var{si\_code} di
+\var{siginfo} il valore \macro{SI\_QUEUE} e il campo \var{si\_value} riceverà
+quanto inviato con \param{value}. Se invece si è installato un manipolatore
+nella forma classica il segnale sarà generato, ma in caso di emissioni
+multiple prima dell'esecuzione del manipolatore, sarà ricevuto una sola volta.
+
 
 
 %%% Local Variables: