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
\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}
\end{table}
Come si può notare in \figref{fig:sig_sigaction} \func{sigaction}
-permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ma in
- Linux è stata aggiunta a partire dai kernel della serie 2.2.x. 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 \var{siginfo\_t}, riportata
-in \figref{fig:sig_siginfo_t}.
+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
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \var{siginfo\_t}.}
+ \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 segnale ricevuto, \var{si\_errno}, che riporta il codice di errore, e
-\var{si\_code}, che viene usato per indicare la ragione per cui è stato emesso
-il segnale (come i dettagli sul tipo di errore per \macro{SIGFPE} e
-\macro{SIGILL}) ed ha valori diversi\footnote{un elenco dettagliato è
- disponibile nella man page di \func{sigaction}.} a seconda del tipo di
-segnale ricevuto.
-
-Il resto della struttura può essere definito come \ctyp{union} ed i valori
+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 POSIX.1b\footnote{NdA trovare quale sono e completare l'informazione.}
-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}) e \macro{SIGPOLL} avvalorano \var{si\_fd}
-con il numero del file descriptor.
+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
\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 */
/* return remaining time */
return alarm(0);
}
-/*
- * Signal Handler for SIGALRM
- */
void alarm_hand(int sig)
{
return; /* just return to interrupt sigsuspend */
\var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
\func{sigsuspend}.
-In questo modo non sono più possibili race condition\index{race conditionx}
+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}.
\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
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,
\func{longjmp}.
+
+\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]
+
+ 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]
+
+ 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{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:
%%% mode: latex
%%% TeX-master: "gapil"