Corretta ed integrata la parte relativa alla notifica dei sengali, e
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index de0823f17fe51dc909b681e6eeec760bed399641..5f3b5af947d766bd91e0bf8f15394248bbf19387 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -3847,12 +3847,14 @@ processo che esegue la creazione).
 Le code di messaggi non sono ancora supportate nel kernel ufficiale, esiste
 però una implementazione sperimentale di Michal Wronski e Krzysztof
 Benedyczak,\footnote{i patch al kernel e la relativa libreria possono essere
 Le code di messaggi non sono ancora supportate nel kernel ufficiale, esiste
 però una implementazione sperimentale di Michal Wronski e Krzysztof
 Benedyczak,\footnote{i patch al kernel e la relativa libreria possono essere
-  trovati \href{http://www.mat.uni.torun.pl/~wrona/posix_ipc}
-  {http://www.mat.uni.torun.pl/\~{}wrona/posix\_ipc}.}.  In generale, come le
-corrispettive del SysV IPC, le code di messaggi sono poco usate, dato che i
-socket\index{socket}, nei casi in cui sono sufficienti, sono più comodi, e che
-in casi più complessi la comunicazione può essere gestita direttamente con
-mutex e memoria condivisa con tutta la flessibilità che occorre.
+trovati su
+\href{http://www.mat.uni.torun.pl/~wrona/posix_ipc}
+{http://www.mat.uni.torun.pl/\~{}wrona/posix\_ipc}.}.
+In generale, come le corrispettive del SysV IPC, le code di messaggi sono poco
+usate, dato che i socket\index{socket}, nei casi in cui sono sufficienti, sono
+più comodi, e che in casi più complessi la comunicazione può essere gestita
+direttamente con mutex e memoria condivisa con tutta la flessibilità che
+occorre.
 
 Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel cui
 siano stati opportunamente applicati i relativi patch, occorre utilizzare la
 
 Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel cui
 siano stati opportunamente applicati i relativi patch, occorre utilizzare la
@@ -4010,7 +4012,7 @@ essere richiesta da qualche altro processo.
 Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la
 funzione \funcd{mq\_unlink}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
 Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la
 funzione \funcd{mq\_unlink}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
-{int mq_unlink(const char *name)}
+{int mq\_unlink(const char *name)}
 
 Rimuove una coda di messaggi.
   
 
 Rimuove una coda di messaggi.
   
@@ -4132,11 +4134,12 @@ prototipi sono:
 \begin{functions}
   \headdecl{mqueue.h} 
   
 \begin{functions}
   \headdecl{mqueue.h} 
   
-  \funcdecl{ssize\_t mq\_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
-    unsigned int *msg_prio)} Effettua la ricezione di un messaggio da una coda.
+  \funcdecl{ssize\_t mq\_receive(mqd\_t mqdes, char *msg\_ptr, size\_t
+    msg\_len, unsigned int *msg\_prio)}   
+  Effettua la ricezione di un messaggio da una coda.
   
   \funcdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
   
   \funcdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
-    msg\_len, unsigned int *msg\_prio, const struct timespec *abs'_timeout)}
+    msg\_len, unsigned int *msg\_prio, const struct timespec *abs\_timeout)}
   Effettua la ricezione di un messaggio da una coda entro il tempo
   \param{abs\_timeout}.
   
   Effettua la ricezione di un messaggio da una coda entro il tempo
   \param{abs\_timeout}.
   
@@ -4153,25 +4156,34 @@ prototipi sono:
     \item[\errcode{ETIMEDOUT}] La ricezione del messaggio non è stata
       effettuata entro il tempo stabilito.
     \end{errlist}    
     \item[\errcode{ETIMEDOUT}] La ricezione del messaggio non è stata
       effettuata entro il tempo stabilito.
     \end{errlist}    
-    \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o \errval{EINVAL}.}
+    ed inoltre \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o
+    \errval{EINVAL}.}
 \end{functions}
 
 La funzione estrae dalla coda il messaggio a priorità più alta, o il più
 \end{functions}
 
 La funzione estrae dalla coda il messaggio a priorità più alta, o il più
-vecchio fra quelli della stessa priorità, una volta ricevuto il messaggio
+vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio
 viene tolto dalla coda e la sua dimensione viene restituita come valore di
 viene tolto dalla coda e la sua dimensione viene restituita come valore di
-ritorno. Se la dimensione specificata da \param{msg\_len} non è sufficiente a
-contenere il messaggio le funzioni, al contrario di quanto avveniva nelle code
-di messaggi di SysV, ritornano un errore di \errcode{EMSGSIZE} senza estrarre
-il messaggio.  È pertanto opportuno chiamare sempre \func{mq\_getaddr} prima
-di eseguire una ricezione, per allocare per i messaggi dei buffer di
-dimensione opportuna.
+ritorno.
 
 
-Se si specifica un valore non nullo per l'argomento \param{msg\_prio} il
-valore della priorità del messaggio viene memorizzato all'indirizzo da esso
-puntato. Si noti che con le code di messaggi POSIX non si ha la possibilità di
-selezionare quale messaggio estrarre in base alla priorità, a differenza di
-quanto avveniva con le code di messaggi di SysV che permettono la selezione in
-base al valore del campo \var{mtype}.
+Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere
+il messaggio, entrambe le funzioni, al contrario di quanto avveniva nelle code
+di messaggi di SysV, ritornano un errore di \errcode{EMSGSIZE} senza estrarre
+il messaggio.  È pertanto opportuno eseguire sempre una chiamata a
+\func{mq\_getaddr} prima di eseguire una ricezione, in modo da ottenere la
+dimensione massima dei messaggi sulla coda, per poter essere in grado di
+allocare dei buffer sufficientemente ampi per la lettura.
+
+Se si specifica un puntatore per l'argomento \param{msg\_prio} il valore della
+priorità del messaggio viene memorizzato all'indirizzo da esso indicato.
+Qualora non interessi usare la priorità dei messaggi si può specificare
+\var{NULL}, ed usare un valore nullo della priorità nelle chiamate a
+\func{mq\_send}.
+
+Si noti che con le code di messaggi POSIX non si ha la possibilità di
+selezionare quale messaggio estrarre con delle condizioni sulla priorità, a
+differenza di quanto avveniva con le code di messaggi di SysV che permettono
+invece la selezione in base al valore del campo \var{mtype}. Qualora non
+interessi usare la priorità dei messaggi si
 
 Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si
 sia selezionata la modalità non bloccante; in tal caso entrambe ritornano
 
 Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si
 sia selezionata la modalità non bloccante; in tal caso entrambe ritornano
@@ -4180,7 +4192,16 @@ differenza fra le due funzioni 
 passato il tempo massimo \param{abs\_timeout} ritorna comunque con un errore
 di \errcode{ETIMEDOUT}.
 
 passato il tempo massimo \param{abs\_timeout} ritorna comunque con un errore
 di \errcode{ETIMEDOUT}.
 
-Un'altra caratteristica specifica delle code di messaggi POSIX è la
+Uno dei problemi sottolineati da Stevens in \cite{UNP2}, comuni ad entrambe le
+tipologie di code messaggi, è che non è possibile per chi riceve identificare
+chi è che ha inviato il messaggio, in particolare non è possibile sapere da
+quale utente esso provenga. Infatti, in mancanza di un meccanismo interno al
+kernel, anche se si possono inserire delle informazioni nel messaggio, queste
+non possono essere credute, essendo completamente dipendenti da chi lo invia.
+Vedremo però come, attraverso l'uso del meccanismo di notifica, sia possibile
+superare questo problema.
+
+Una caratteristica specifica delle code di messaggi POSIX è infatti la
 possibilità di usufruire di un meccanismo di notifica asincrono; questo può
 essere attivato usando la funzione \funcd{mq\_notify}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
 possibilità di usufruire di un meccanismo di notifica asincrono; questo può
 essere attivato usando la funzione \funcd{mq\_notify}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
@@ -4212,13 +4233,18 @@ particolare il campo \var{sigev\_notify} deve essere posto a
 \const{SIGEV\_SIGNAL}\footnote{il meccanismo di notifica basato sui thread,
   specificato tramite il valore \const{SIGEV\_THREAD}, non è implementato.} ed
 il campo \var{sigev\_signo} deve indicare il valore del segnale che sarà
 \const{SIGEV\_SIGNAL}\footnote{il meccanismo di notifica basato sui thread,
   specificato tramite il valore \const{SIGEV\_THREAD}, non è implementato.} ed
 il campo \var{sigev\_signo} deve indicare il valore del segnale che sarà
-inviato al processo.
+inviato al processo. Inoltre il campo \var{sigev\_value} (la cui definizione è
+riportata in \figref{fig:sig_sigval}) permette di restituire al gestore del
+segnale un valore numerico o un indirizzo.
 
 La funzione registra il processo chiamante per la notifica se
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
 inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
 che un solo processo alla volta può essere registrato, la funzione fallisce
 
 La funzione registra il processo chiamante per la notifica se
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
 inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
 che un solo processo alla volta può essere registrato, la funzione fallisce
-con \errcode{EBUSY} se c'è un altro processo già registrato.
+con \errcode{EBUSY} se c'è un altro processo già registrato.  Si tenga
+presente inoltre che alla chiusura del descrittore (e quindi anche all'uscita
+del processo) ogni eventuale registrazione di notifica presente viene
+cancellata.
 
 La notifica avviene all'arrivo di un messaggio in una coda vuota (e non se ci
 sono messaggi sulla coda), in tal caso il segnale specificato da
 
 La notifica avviene all'arrivo di un messaggio in una coda vuota (e non se ci
 sono messaggi sulla coda), in tal caso il segnale specificato da
@@ -4229,6 +4255,15 @@ tenga presente per
 enventuale messaggio viene immediatamente inviato a quest'ultimo, e per il
 meccanismo di notifica funziona tutto come se la coda fosse restata vuota.
 
 enventuale messaggio viene immediatamente inviato a quest'ultimo, e per il
 meccanismo di notifica funziona tutto come se la coda fosse restata vuota.
 
+L'invio del segnale avvalora i campi seguenti campi di \struct{siginfo\_t} (la
+cui definizione è in \figref{fig:sig_siginfo_t}): \var{si\_pid} con il
+\acr{pid} del processo che ha emesso il segnale, \var{si\_uid} con l'userid
+effettivo, \var{si\_code} con \const{SI\_MESGQ}, e \var{si\_errno} a 0. Questo
+ci dice che, se si effettua la ricezione usando esclusivamente il meccanismo
+di notifica, è possibile ottenere le informazioni sul processo che ha inserito
+un messaggio usando un gestore per il segnale in forma estesa (si ricordi
+quanto già detto al proposito in \secref{sec:sig_sigaction} e
+\secref{sec:sig_real_time}).