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}
 
 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
 ne respecte absolument pas le principe de moindre surprise, mais les différentes