Partager via


Entrée/sortie superposée

Windows Sockets 2 introduit des E/S superposées et nécessite que tous les fournisseurs de transport prennent en charge cette fonctionnalité. Les E/S qui se chevauchent peuvent être effectuées uniquement sur les sockets créés via la fonction WSPSocket avec l’ensemble d’indicateurs de WSA_FLAG_OVERLAPPED et suivre le modèle établi dans Windows.

Pour la réception, un client utilise WSPRecv ou WSPRecvFrom pour fournir des mémoires tampons dans lesquelles les données doivent être reçues. Si une ou plusieurs mémoires tampons sont publiées avant le moment où les données ont été reçues par le réseau, il est possible que les données soient placées immédiatement dans les mémoires tampons de l’utilisateur dès qu’elles arrivent et évitent ainsi l’opération de copie qui se produit autrement. Si les données arrivent lorsque des mémoires tampons de réception ont déjà été publiées, elles sont copiées immédiatement dans les mémoires tampons de l’utilisateur. Si les données arrivent lorsqu’aucune mémoire tampon de réception n’a été publiée par l’application, le fournisseur de services a recours au style synchrone d’opération où les données entrantes sont mises en mémoire tampon en interne jusqu’à ce que le client émet un appel de réception et fournit ainsi une mémoire tampon dans laquelle les données peuvent être copiées. Une exception à ceci serait si l’application a utilisé WSPSetSockOpt pour définir la taille de la mémoire tampon de réception sur zéro. Dans cet exemple, les protocoles fiables autorisent uniquement la réception des données lorsque des mémoires tampons d’application ont été publiées et les données sur des protocoles non fiables seraient perdues.

Côté envoi, les clients utilisent WSPSend ou WSPSendTo pour fournir des pointeurs à des mémoires tampons remplies, puis s’accordent à ne pas déranger les mémoires tampons tant que le réseau n’a pas consommé le contenu de la mémoire tampon.

Les appels envoyés et reçus se chevauchent immédiatement. Une valeur de retour de zéro indique que l’opération d’E/S s’est terminée immédiatement et que l’indication d’achèvement correspondante s’est déjà produite. Autrement dit, l’objet d’événement associé a été signalé ou la routine d’achèvement a été mise en file d’attente via WPUQueueApc. Une valeur de retour de SOCKET_ERROR couplée à un code d’erreur de WSA_IO_PENDING indique que l’opération qui se chevauche a été lancée avec succès et qu’une indication ultérieure sera fournie lorsque les mémoires tampons d’envoi ont été consommées ou lorsque les mémoires tampons de réception sont remplies. Tout autre code d’erreur indique que l’opération qui se chevauche n’a pas été lancée avec succès et qu’aucune indication d’achèvement n’est à venir.

Les opérations d’envoi et de réception peuvent se chevaucher. Les fonctions de réception peuvent être appelées plusieurs fois pour publier des mémoires tampons de réception en préparation des données entrantes, et les fonctions d’envoi peuvent être appelées plusieurs fois pour mettre en file d’attente plusieurs mémoires tampons à envoyer. Notez que si une série de mémoires tampons d’envoi superposées est envoyée dans l’ordre fourni, les indications d’achèvement correspondantes peuvent se produire dans un ordre différent. De même, côté réception, les mémoires tampons seront renseignées dans l’ordre dans lequel elles sont fournies, mais les indications d’achèvement peuvent se produire dans un ordre différent.

La fonctionnalité d’achèvement différée des E/S superposées est également disponible pour WSPIoctl.

Livraison d’indications d’achèvement

Les fournisseurs de services ont deux façons d’indiquer la saisie semi-automatique superposée : définition d’un objet d’événement spécifié par le client ou appel d’une routine d’achèvement spécifiée par le client. Dans les deux cas, une structure de données, WSAOVERLAPPED, est associée à chaque opération superposée. Cette structure est allouée par le client et utilisée par celui-ci pour indiquer l’objet d’événement (le cas échéant) à définir lorsque la saisie semi-automatique se produit. La structure WSAOVERLAPPED peut être utilisée par le fournisseur de services comme emplacement pour stocker un handle dans les résultats (par exemple, le nombre d’octets transférés, les indicateurs mis à jour, les codes d’erreur, etc.) pour une opération qui se chevauche. Pour obtenir ces résultats, les clients doivent appeler WSPGetOverlappedResult, en passant un pointeur à la structure qui se chevauche.

Si l’indication d’achèvement basée sur les événements est sélectionnée pour une demande d’E/S superposée particulière, la routine WSPGetOverlappedResult peut elle-même être utilisée par les clients pour interroger ou attendre la fin de l’opération superposée. Si l’indication d’achèvement basée sur la routine est sélectionnée pour une requête d’E/S qui se chevauche, seule l’option d’interrogation de WSPGetOverlappedResult est disponible. Un client peut également utiliser d’autres moyens d’attendre (comme l’utilisation de WSAWaitForMultipleEvents) jusqu’à ce que l’objet d’événement correspondant ait été signalé ou que la routine d’achèvement spécifiée ait été appelée par le fournisseur de services. Une fois l’achèvement indiqué, le client peut appeler WSPGetOverlappedResult, avec l’attente que l’appel se termine immédiatement.

Appel de routines d’achèvement d’E/S de socket

Si le paramètre lpCompletionRoutine à une opération superposée n’est pas NULL, il incombe au fournisseur de services d’organiser l’appel de la routine d’achèvement spécifiée par le client lorsque l’opération se chevauche. Étant donné que la routine d’achèvement doit être exécutée dans le contexte du même thread qui a lancé l’opération superposée, elle ne peut pas être appelée directement à partir du fournisseur de services. Le Ws2_32.DLL offre un mécanisme d’appel de procédure asynchrone (APC) pour faciliter l’appel de routines d’achèvement.

Un fournisseur de services organise l’exécution d’une fonction dans le thread approprié en appelant WPUQueueApc. Cette fonction peut être appelée à partir de n’importe quel contexte de processus et de thread, même un contexte différent du thread et du processus utilisé pour lancer l’opération qui se chevauche.

WPUQueueApc prend comme paramètres d’entrée un pointeur vers une structure WSATHREADID, un pointeur vers une fonction APC à appeler et une valeur de contexte 32 bits qui est ensuite passée à la fonction APC. Les fournisseurs de services sont toujours fournis avec un pointeur vers la structure WSATHREADID appropriée par le biais du paramètre lpThreadId vers la fonction superposée. Le fournisseur doit stocker localement la structure WSATHREADID et fournir un pointeur vers cette copie de la structure WSATHREADID en tant que paramètre d’entrée pour WPUQueueApc. Une fois la fonction WPUQueueApc retournée, le fournisseur peut supprimer sa copie du WSATHREADID.

La procédure WPUQueueApc met simplement en file d’attente des informations suffisantes pour appeler la fonction APC indiquée avec les paramètres donnés, mais ne l’appelle pas. Lorsque le thread cible entre dans un état d’attente alertable, ces informations sont mise en file d’attente et un appel est passé à la fonction APC dans ce thread cible et contexte de processus. Étant donné que le mécanisme APC ne prend en charge qu’une seule valeur de contexte 32 bits, la fonction APC ne peut pas elle-même être la routine d’achèvement spécifiée par le client, ce qui implique davantage de paramètres. Le fournisseur de services doit plutôt fournir un pointeur vers sa propre fonction APC qui utilise la valeur de contexte fournie pour accéder aux informations de résultat nécessaires pour l’opération qui se chevauche, puis appelle la routine d’achèvement spécifiée par le client.

Pour les fournisseurs de services où un composant en mode utilisateur implémente des E/S superposées, l’utilisation classique du mécanisme APC est la suivante :

  • Une fois l’opération d’E/S terminée, le fournisseur alloue une petite mémoire tampon et le packe avec un pointeur vers la procédure d’achèvement fournie par le client et les valeurs de paramètre à passer à la procédure.
  • Il met en file d’attente un APC, en spécifiant le pointeur vers la mémoire tampon comme valeur de contexte et sa propre procédure intermédiaire comme procédure cible.
  • Lorsque le thread cible entre finalement dans l’état d’attente alertable, la procédure intermédiaire du fournisseur de services est appelée dans le contexte de thread approprié.
  • La procédure intermédiaire décompresse simplement les paramètres, libère la mémoire tampon et appelle la procédure d’achèvement fournie par le client.
  • Pour les fournisseurs de services où un composant en mode noyau implémente des E/S qui se chevauchent, une implémentation classique est similaire, sauf que l’implémentation utilise des interfaces noyau standard pour mettre en file d’attente l’APC.

La description des interfaces de noyau pertinentes est en dehors de la portée de la spécification Windows Sockets 2.

Note

Les fournisseurs de services doivent autoriser les clients Windows Sockets 2 à appeler des opérations d’envoi et de réception dans le contexte de la routine d’achèvement des E/S de socket et garantir que pour un socket donné, les routines d’achèvement d’E/S ne seront pas imbriquées.

 

Dans certaines circonstances, un fournisseur de services en couches peut avoir besoin d’initier et d’effectuer des opérations superposées à partir d’un thread de travail interne. Dans ce cas, un WSATHREADID ne serait pas disponible à partir d’un appel de fonction entrant. L’interface du fournisseur de services fournit un appel, WPUOpenCurrentThread, pour obtenir un WSATHREADID pour le thread actuel. Lorsque cette WSATHREADID n’est plus nécessaire, ses ressources doivent être retournées en appelant WPUCloseThread.