2017-10-06 7 views
1

Le contexte pour cela: Je travaille sur l'implémentation d'un adaptateur de flux simple au-dessus d'une bibliothèque de wrappers RDMA intégrant Boost ASIO. Le problème que je rencontre est que l'agrégateur boost::asio::async_read appelé par le code client est suspendu même si le flux a renvoyé suffisamment de données pour remplir le tampon, s'il n'y a plus de données en attente dans le tampon de réception interne. Le débogage semble indiquer qu'il appelle la méthode async_read_some de mon adaptateur de flux avec un seul tampon de taille 0.Est-ce que `stream.async_read_some (null_buffers, handler)` doit être terminé immédiatement ou non?

La documentation que j'ai trouvée semble être en conflit pour savoir si cette opération doit être terminée immédiatement ou non. D'une part, the AsyncReadStream concept specification dit:

Si la taille totale de tous les tampons dans la séquence mb est 0, l'opération de lecture asynchrone doit immédiatement remplir et passer 0 comme argument au gestionnaire qui spécifie le nombre d'octets lis.

D'autre part, the overview of boost::asio::null_buffers dit:

Une opération null_buffers ne retourne pas jusqu'à ce que l'objet E/S est « prêt » pour effectuer l'opération.

(Et en fait, d'ailleurs je compte sur cela pour enregistrer les gestionnaires à appeler lorsque le rdma_cm et ibverbs canal d'achèvement FDs indiquent des événements disponibles.) Mais en regardant la mise en œuvre de null_buffers, il semblerait que c'est juste un objet statique ne contenant pas de tampons, donc cela semblerait satisfaire la condition d'une séquence avec la taille totale de tous les tampons étant 0.

Donc, je suis confus quant à la façon dont ma méthode async_read_some devrait gérer le cas d'essayer lire 0 octets. Comme une conjecture, peut-être devrait-il être quelque chose comme: sur une séquence vraiment vide comme null_buffers il devrait compléter seulement quand il y a des données disponibles dans le tampon de réception, alors que s'il a une séquence non vide avec la longueur totale des tampons égale à 0 alors il devrait compléter immédiatement indépendamment de l'état du tampon de réception?

Répondre

0

Remarquenull_buffers a été dépréciées depuis Boost 1.66.0: "(Deprecated: Use the socket/descriptor wait() and async_wait() member functions.)"

En tant que conjecture sauvage, il faudrait peut-être quelque chose comme: sur une séquence vraiment vide comme null_buffers il doit remplir que lorsque il y a des données disponibles dans le tampon de réception, alors que s'il a une séquence non vide avec une longueur totale des tampons égale à 0 alors il devrait terminer immédiatement quel que soit l'état du tampon de réception?

n ° null_buffers ne sont PAS des "tampons vides" ou des "tampons de longueur nulle". C'est "pas de tampon", signalant aux routines ASIO qu'il n'y a pas de buffers (donc la taille ne peut logiquement être considérée comme nulle).

Toutes les notes d'achèvement relatives à la taille de la mémoire tampon ne sont pas pertinentes, car aucun tampon n'est présent. La pièce de documentation pertinente est Reactor Style Operations.

Vous avez dit correctement: en passant null_buffers signaux que vous voulez une opération de type réacteur à tisser dans le sous-système d'événements asio (signification, vous pouvez async attendre une prise pour être prêt pour la lecture/écriture, puis faire la par exemple, en transmettant nativement le descripteur de socket sous-jacent à une API tierce qui ne prend pas en charge les E/S asynchrones de manière native

+0

Dans une autre recherche, j'ai trouvé que par exemple '' a une surcharge spécifique pour 'async_read_some' sur' null_buffers' Donc je suppose que cela signifierait que c'est différent même du comportement sur tout autre conteneur vide, par exemple 'std :: vector no_bufs; posix_stream. async_read_some (no_bufs, [] {std :: cout << "Terminer s immédiatement! \ n "; }); posix_stream.async_read_some (boost :: asio :: null_buffers {}, [] {std :: cout << "Prêt à lire! \ n";}); 'Ma compréhension est-elle correcte? –

+0

C'est exactement ce que ma réponse a dit. – sehe

+0

OK, avant que je pose la question je pensais à la distinction entre 'vector no_bufs;' et 'char dummy; le vecteur one_empty_buf {{& dummy, 0}}; 'où le premier pourrait également être considéré comme" no buffers "alors que le second est" un seul buffer vide ". –