From: Simone Piccardi Date: Fri, 26 Dec 2003 21:58:10 +0000 (+0000) Subject: Aggiunti i due esempi di pselect lasciati indietro, specificato il X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=271b1b8bf70e62b5ab4457895664400ff6f51973;p=gapil.git Aggiunti i due esempi di pselect lasciati indietro, specificato il significato di un valore negativo per il campo fd di polld e classificato il traffico dei socket tcp per poll. --- diff --git a/fileadv.tex b/fileadv.tex index 19f7dab..a4f8229 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -357,7 +357,8 @@ viene utilizzato per specificare il file descriptor relativo al file da controllare, mentre nel campo \var{events} deve essere specificata una maschera binaria data in ingresso che indichi il tipo di evento che si vuole controllare, il kernel restituirà il relativo risultato nel campo -\var{revents}. +\var{revents}. Usando un valore negativo per \param{fd} la corrispondente +struttura sarà ignorata da \func{poll}. Le costanti che definiscono i valori relativi ai bit usati nelle maschere binarie dei campi \var{events} e \var{revents} sono riportati in @@ -1124,6 +1125,14 @@ l'emissione di un segnale di violazione di accesso (\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non consentono questo tipo di accesso. +\begin{figure}[!htb] + \centering + \includegraphics[width=10cm]{img/mmap_boundary} + \caption{Schema della mappatura in memoria di una sezione di file di + dimensioni non corrispondenti al bordo di una pagina.} + \label{fig:file_mmap_boundary} +\end{figure} + È invece assai diversa la questione relativa agli accessi al di fuori della regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe ritenere che anch'essi debbano generare un segnale di violazione di accesso; @@ -1137,15 +1146,6 @@ file non rientra nei confini di una pagina: in tal caso verr mappato su un segmento di memoria che si estende fino al bordo della pagina successiva. -\begin{figure}[htb] - \centering - \includegraphics[width=10cm]{img/mmap_boundary} - \caption{Schema della mappatura in memoria di una sezione di file di - dimensioni non corrispondenti al bordo di una pagina.} - \label{fig:file_mmap_boundary} -\end{figure} - - In questo caso è possibile accedere a quella zona di memoria che eccede le dimensioni specificate da \param{lenght}, senza ottenere un \const{SIGSEGV} poiché essa è presente nello spazio di indirizzi del processo, anche se non è diff --git a/listati/pselect_norace.c b/listati/pselect_norace.c new file mode 100644 index 0000000..f5f9c39 --- /dev/null +++ b/listati/pselect_norace.c @@ -0,0 +1,13 @@ +while (1) { + sigprocmask(SIG_BLOCK, &newmask, &oldmask); + if (receive_signal != 0) handle_signal(); + n = pselect(nfd, rset, wset, eset, NULL, &oldmask); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + if (n < 0) { + if (errno == EINTR) { + continue; + } + } else { + handle_filedata(); + } +} diff --git a/listati/select_race.c b/listati/select_race.c new file mode 100644 index 0000000..91509b5 --- /dev/null +++ b/listati/select_race.c @@ -0,0 +1,11 @@ +while (1) { + sigprocmask(SIG_BLOCK, &newmask, &oldmask); + if (receive_signal != 0) handle_signal(); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + n = select(nfd, rset, wset, eset, NULL); + if (n < 0) { + if (errno == EINTR) { + continue; + } + } else handle_filedata(); +} diff --git a/tcpsockadv.tex b/tcpsockadv.tex index 28b2318..c8e9ec4 100644 --- a/tcpsockadv.tex +++ b/tcpsockadv.tex @@ -693,15 +693,52 @@ fine. -\subsection{Un esempio di I/O multiplexing con \func{poll}} +\subsection{I/O multiplexing con \func{poll}} \label{sec:TCP_serv_poll} -Abbiamo visto in \secref{sec:TCP_serv_select} come creare un server che -utilizzi l'I/O multiplexing attraverso l'impiego della funzione \func{select}, -ma in \secref{sec:file_multiplexing} abbiamo visto come la funzione -\func{poll} costituisca una alternativa a \func{select} con delle funzionalità -migliori, vediamo allora come reimplementare il nostro servizio usando questa -funzione. +Finora abbiamo trattato le problematiche risolubili con l'I/O multiplexing +impiegando la funzione \func{select}; questo è quello che avviene nella +maggior parte dei casi, in quanto essa è nata sotto BSD proprio per affrontare +queste problematiche con i socket. Abbiamo però visto in +\secref{sec:file_multiplexing} come esistono altre funzioni che permettono di +affrontare lo stesso problema e come la funzione \func{poll} possa costituire +una alternativa a \func{select}, con alcuni vantaggi.\footnote{non soffrendo + delle limitazioni dovute all'uso dei \textit{file descriptor set}.} + +Ancora una volta in \secref{sec:file_poll} abbiamo trattato la funzione in +maniera generica, parlando di file descriptor, ma come per \func{select} +quando si ha a che fare con dei socket il concetto di essere \textsl{pronti} +per l'I/O deve essere specificato nei dettagli, per tener conto delle +condizioni della rete. Inoltre deve essere specificato come viene classificato +il traffico nella suddivisione fra dati normali e prioritari. In generale +pertanto: +\begin{itemize} +\item i dati trasmessi su un socket vengono considerati traffico normale, + pertanto vengono rilevati da una selezione con \const{POLLIN} o + \const{POLLRDNORM}. +\item i dati \textit{out-of-band} su un socket TCP vengono considerati + traffico prioritario e vengono rilevati da una condizione \const{POLLIN}, + \const{POLLPRI} o \const{POLLRDBAND}. +\item la chiusura di una connessione (cioè la ricezione di un segmento FIN) + viene considerato traffico normale, pertanto viene rilevato da una + condizione \const{POLLIN} o \const{POLLRDNORM}, ma una conseguente chiamata + a \func{read} restituirà 0. +\item la presenza di un errore sul socket (sia dovuta ad un segmento RST che a + timeout) viene considerata traffico normale, ma viene segnalata anche dalla + condizione \const{POLLERR}. +\item la presenza di una nuova connessione su un socket in ascolto può essere + considerata sia traffico normale che prioritario, nel caso di Linux + l'implementazione la classifica come normale. +\end{itemize} + +Come esempio dell'uso di \func{poll} proviamo allora a reimplementare il +server \textit{echo} secondo lo schema di \figref{fig:TCP_echo_multiplex} +usando \func{poll} al posto di \func{select}. In questo caso dovremo fare +qualche modifica, + + + + \section{Le opzioni dei socket}