Ver código fonte

chapters/windows_eventloop: ajout des IOCP et conclusion

Alexandre Janniaux 6 anos atrás
pai
commit
870aa7bac0
1 arquivos alterados com 87 adições e 1 exclusões
  1. 87 1
      chapters/windows_eventloop.tex

+ 87 - 1
chapters/windows_eventloop.tex

@@ -160,7 +160,93 @@ que le thread sera dans un état alertable, c'est-à-dire se signalera disponibl
 \subsection{IO completion ports}
 \subsection{IO completion ports}
 
 
 Les IO completion ports, ou IOCP pour la suite, permettent d'implémenter un
 Les IO completion ports, ou IOCP pour la suite, permettent d'implémenter un
-système similaire à epoll, dans un modèle par complétion.
+système similaire à epoll, dans un modèle par complétion, en étendant les
+\inltype{OVERLAPPED} IO vues précédemment. L'API n'est cependant pas très claire
+sur beaucoup de points donc elle sera plus longuement décrite ici pour apporter
+des explications dans ce rapport.
+
+Un IOCP peut être créé avec la fonction \inltype{CreateIoCompletionPort} en
+passant \inltype{INVALID_HANDLE_VALUE} comme \inltype{FileHandle} et
+\inltype{NULL} comme \inltype{ExistingCompletionPort}.
+
+% TODO: https://docs.microsoft.com/en-us/windows/desktop/fileio/createiocompletionport
+\begin{code}{c}{Prototype de CreateIoCompletionPort sur MSDN}
+HANDLE WINAPI CreateIoCompletionPort(
+    _In_     HANDLE    FileHandle,
+    _In_opt_ HANDLE    ExistingCompletionPort,
+    _In_     ULONG_PTR CompletionKey,
+    _In_     DWORD     NumberOfConcurrentThreads
+);
+\end{code}
+
+Le paramètre \inltype{CompletionKey} est ignoré dans ce cas, et le paramètre
+\inltype{NumberOfConcurrentThreads} permet d'indiquer à l'IOCP combien de thread
+vont pouvoir simultanément recevoir les notifications de nouveaux messages. Ce
+paramètre ne démarrre pas de nouveaux threads mais sert seulement à
+l'ordonnancement dans le cas où plusieurs threads demanderaient des
+notifications au port. Dans ce dernier cas, chacun des threads recevra des
+notifications pour des opérations différentes, mais cela ne nous concerne pas
+ici.
+
+Nous pouvons ensuite ajouter des opérations en utilisant la même fonction, mais
+en renseignant \inltype{FileHandle} comme étant l'objet sur lequel l'opération a
+été effectuée, \inltype{ExistingCompletionPort} comme étant le \inltype{HANDLE}
+créé dans l'appel précédent et \inltype{CompletionKey} comme étant une valeur
+arbitraire qui nous servira à retrouver l'opération plus tard.
+
+Il est possible de créer un port tout en associant un \inltype{HANDLE} à la
+construction, mais le cas ne nous intéresse pas pour l'implémentation de
+\inltype{vlc_msg_poller_t}.
+
+Une fois les opérations associées au port, on peut utiliser
+\inltype{GetQueuedCompletionStatus} pour récupérer un paquet de complétion.
+
+% TODO: https://msdn.microsoft.com/en-us/library/Aa364986(v=VS.85).aspx
+\begin{code}{c}{Prototype de GetQueuedCompletionStatus sur MSDN}
+BOOL WINAPI GetQueuedCompletionStatus(
+    _In_  HANDLE       CompletionPort,
+    _Out_ LPDWORD      lpNumberOfBytes,
+    _Out_ PULONG_PTR   lpCompletionKey,
+    _Out_ LPOVERLAPPED *lpOverlapped,
+    _In_  DWORD        dwMilliseconds
+);
+\end{code}
+
+Cette fonction attendra la fin d'une opération en cours, et plus exactement
+l'arrivée d'un paquet de complétion, pour retourner, mais permettra de récupérer
+la structure \inltype{OVERLAPPED} contenant les données et informations liées à
+l'opération effectuée.
+
+Enfin, il sera possible de poster une notification sans effectuer d'opération en
+appelant \inltype{PostQueuedCompletionStatus}, afin de débloquer la boucle
+événementielle par exemple.
+
+% TODO: https://docs.microsoft.com/en-us/windows/desktop/FileIO/postqueuedcompletionstatus
+\begin{code}{c}{Prototype de PostQueuedCompletionStatus}
+BOOL WINAPI PostQueuedCompletionStatus(
+    _In_     HANDLE       CompletionPort,
+    _In_     DWORD        dwNumberOfBytesTransferred,
+    _In_     ULONG_PTR    dwCompletionKey,
+    _In_opt_ LPOVERLAPPED lpOverlapped
+);
+\end{code}
+
+\section{Implémentation et conclusions pour la boucle événementielle}
+
+Ayant déjà décrit \inltype{vlc_msg_poller_t} pour la partie Linux et
+extensivement expliqué le fonctionnement de l'API d'IOCP, il reste
+principalement à décrire l'implémentation du modèle par complétion dans la
+situation d'attente de message.
+
+Contrairement à Linux, les IOCP ne vont pas signaler quand un des
+\inltype{HANDLE} sera prêt à être lu mais plutôt quand les données auront
+effectivement été lues. Il faut donc allouer un tampon par requête de lecture.
+La méthodologie sera alors de dédier un tampon par \inltype{HANDLE} puis
+d'effectuer toutes les opérations de lecture. Lorsqu'une des opérations est
+considérée comme terminée, on pourra traiter le message puis relancer
+l'opération de lecture.
+
+% TODO: snippet de code
 
 
 En résumé, la gestion des entrées sorties et des erreurs proposées par Windows
 En résumé, la gestion des entrées sorties et des erreurs proposées par Windows
 ne respecte absolument pas le principe de moindre surprise, mais les différentes
 ne respecte absolument pas le principe de moindre surprise, mais les différentes