|
@@ -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
|