Aggiunti i due esempi di pselect lasciati indietro, specificato il
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 26 Dec 2003 21:58:10 +0000 (21:58 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 26 Dec 2003 21:58:10 +0000 (21:58 +0000)
significato di un valore negativo per il campo fd di polld e classificato il
traffico dei socket tcp per poll.

fileadv.tex
listati/pselect_norace.c [new file with mode: 0644]
listati/select_race.c [new file with mode: 0644]
tcpsockadv.tex

index 19f7dabdf8f371337bc8bec1b4f235d2cddc37f4..a4f8229095c3ccb4dc5ab7a272330072dca3c446 100644 (file)
@@ -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
 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
 
 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.
 
 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;
 È 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.
 
 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 è
 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 (file)
index 0000000..f5f9c39
--- /dev/null
@@ -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 (file)
index 0000000..91509b5
--- /dev/null
@@ -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();
+}
index 28b2318a09a93b8c6dfa69213563f4020d855c7c..c8e9ec4ace77b08e43c309aaffb01e43d0136737 100644 (file)
@@ -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}
 
 \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}
 
 
 \section{Le opzioni dei socket}