X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=elemtcp.tex;fp=elemtcp.tex;h=766974ff749966578a05de3f57d0230ed07c7a84;hp=534dd398f18819943c1811ed5bbb63fcf5d556ab;hb=7b6b988cdddf6e996eb88d02bd13bbe7e2936d73;hpb=533949c32eff5d8c6cc4020b774befb5741ce8c2 diff --git a/elemtcp.tex b/elemtcp.tex index 534dd39..766974f 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -2005,14 +2005,63 @@ Baster \noindent all'esempio illustrato in \figref{fig:TCP_echo_server_code}. -In questo modo però si introduce un altro problema, +In questo modo però si introduce un altro problema, il fatto che, come +spiegato in \secref{sec:sig_gen_beha}, quando un programma si trova in stato +di \texttt{sleep} durante l'esecuzione di una system call, questa viene +interrotta alla ricezione di un segnale, per cui alla fine dell'esecuzione del +gestore il programma, se questo ritorna, l'esecuzione del programma riprenderà +con l'uscita dalla system call con un errore di \errcode{EINTR}. + +Questo comporta che quando si chiude il client, con la terminazione del +processo figlio, il padre, che riceve il segnale ed esegue il gestore, +ritornerà dalla \func{accept} (a meno di un caso fortuito in cui il segnale +arriva durante l'esecuzione del programma in risposta ad una connessione) con +un errore di \errcode{EINTR}, terminando a sua volta con un errore del tipo: +\begin{verbatim} + +\end{verbatim} -\subsection{I vari scenari critici} -\label{sec:TCP_echo_critical} +Come accennato in \secref{sec:sig_gen_beha} questo ci mette di fronte a due +possibili soluzioni, la più semplice è quella di modificare il codice di +\func{Signal} per richiedere il riavvio automatico delle system call +interrotte secondo la semantica di BSD, usando l'opzione \const{SA\_RESTART} +di \func{sigaction}; rispetto a quanto visto in \figref{fig:sig_Signal_code} +definiremo allora la nuova funzione \func{SignalRestart} come mostrato in +\figref{fig:sig_SignalRestart_code}. +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15.6cm} + \includecodesample{listati/SignalRestart.c} + \end{minipage} + \normalsize + \caption{La funzione \funcd{SignalRestart}, che installa un gestore di + segnali in semantica BSD.} + \label{fig:sig_SignalRestart_code} +\end{figure} + +Come si può notare questa funzione è identica a \func{Signal}, solo che in +questo caso invece di inizializzare a zero il campo \var{sa\_flags} di +\struct{sigaction} lo si inizializza (\texttt{\small 5}) al valore +\const{SA\_RESTART}. + +Usando questa funzione al posto di \func{Signal} nel server non è necessaria +nessuna altra modifica, le system call interrotte saranno automaticamente +riavviate, e l'errore \errcode{EINTR} non si manifesterà più. + + + +\section{I vari scenari critici} +\label{sec:TCP_echo_critical} +Con le modifiche viste in \secref{sec:TCP_child_hand} il nostro esempio +diventa in grado di affrontare correttamente la gestione ordinaria delle +connessioni, ma un server di rete deve tenere conto che, al contrario di +quanto avviene per i server che operano nei confronti di processi presenti +sulla stessa macchina, la rete è di sua natura inaffidabile, per cui è +necessario essere in grado di gestire tutta una serie di situazioni critiche.