2009-03-24 6 views
0

J'utilise IOCP sur socket UDP, et le socket UDP peut être fermé dans un autre thread. Alors, comment puis-je libérer Per Socket Context et Per I/O Context qui associé à SOCKET en toute sécurité?Port d'achèvement d'E/S, Comment libérer le contexte par socket et le contexte d'E/S?

Lorsque je ferme le socket, il y aura toujours une demande d'E/S non terminée dans la file d'attente du noyau.

Si je libère le contexte juste lorsque le socket est fermé, le GetQueueCompletionStatus peut échouer. Maintenant, ma question est de savoir quand libérer le contexte?

Répondre

1

Utilisez un mutex pour appliquer l'exclusion mutuelle dans une section critique de votre code qui vérifiera la disponibilité du socket et l'ouvrira si nécessaire. Verrouillez la prise à ce fil et relâchez-la de façon appropriée lorsque vous avez terminé.

3

J'utilise le comptage de références sur toutes mes structures de données par socket et par E/S. Cela rend ce genre de chose facile car ils sont supprimés lorsque leurs références tombent à 0. Pour un exemple de code qui montre une façon de le faire, vous pouvez jeter un oeil à mon framework IOCP gratuit que vous pouvez télécharger depuis here.

0

Je réutilise mes structures par socket. Après avoir reçu des événements d'achèvement pour toutes les opérations de lecture et d'écriture requises pour cette connexion, j'appelle TransmitFile avec les indicateurs TF_DISCONNECT et TF_REUSE_SOCKET pour réinitialiser le socket sans avoir à le fermer. Je réinitialise également les données par connexion une fois que l'événement d'achèvement pour l'appel TransmitFile vient à travers.

0

Fermez le connecteur en premier. Vous obtiendrez erreur (je pense que c'est ERROR_OPERATION_ABORTED) à partir de GetQueuedCompletionStatus, puis il est temps de libérer la structure. Il n'y a pas d'autres demandes non terminées sur cette connexion dans la file d'attente du noyau, les paquets d'achèvement sont conservés dans l'ordre FIFO, et le paquet d'erreur sera certainement le dernier pour cette connexion.

+0

Quels sont les paquets en attente? par exemple. Si une lecture et une écriture sont en attente, vous ne savez pas laquelle renverra ERROR_OPERATION_ABORTED en premier, n'est-ce pas? –

+0

Ok. Vous obtenez toujours la clé d'achèvement valide et le paramètre chevauché renvoyé par GetQueuedCompletionStatus(), même avec ERROR_OPERATION_ABORTED. Vous pouvez utiliser l'un ou l'autre pour le contexte que vous voulez libérer. –

+0

Mon point est si vous avez * deux * une écriture et une lecture (donc 2 structures OVERLAPPED en attente d'achèvement d'E/S), vous ne savez pas lequel des deux sera terminé en premier, et qui sera complété en dernier (même si les deux renvoie ERROR_OPERATION_ABORTED ou pas), vous aurez besoin d'un compteur atomique pour établir lequel sera complété * last * et ensuite appeler une routine de nettoyage à partir de là pour libérer la mémoire –