J'ai un code qui ressemble à ceci:epoll_wait semble rester coincé sur EPOLLRDHUP
for (;;) {
errno=0;
epoll_event e = {};
auto wait_r = epoll_wait(g.epoll_fd, &e, 1, 0);
if (wait_r==0) break;
if(wait_r ==-1 && errno==EINTR) {
printf("got EINTR\n");
continue;
}
assert(wait_r == 1);
auto& c = *(Context*)e.data.ptr;
if(e.events & EPOLLERR) {
int error = 0;
socklen_t errlen = sizeof(error);
auto r1 =getsockopt(c.socket, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
assert(r1==0);
printf("Got EPOLLERR 2 %s\n", strerror(error));
}
if(e.events & EPOLLRDHUP || e.events & EPOLLHUP) {
if (e.events & EPOLLRDHUP) {
printf("got to EPOLLRDHUP\n");
}
if (e.events & EPOLLHUP) {
printf("got to EPOLLHUP\n");
}
//continue; // keeps hitting this for same connections
break;
}
if (e.events & EPOLLIN) {
// Does a bunch of reads...
}
}
}
Un seul socket se coincer dans le cas EPOLLRDHUP || EPOLLHUP
. Le socket est probablement fermé, quand j'essaie de le fermer ou de faire EPOLL_CTL_DEL j'obtiens un EBADFD. J'ai cru comprendre qu'epoll se débarrasserait automatiquement de toutes les douilles mortes, mais cela ne semble pas être le cas ... des idées? Un autre problème possible est que sur la socket j'utilise recvmsg/sendmsg et j'envoie des descripteurs de fichier entre les processus, sur ces sockets, qui sont des sockets de flux de domaine Unix. J'ai essayé de faire un dernier recvmsg, mais ça échoue aussi ... Des idées?
Je recommande que votre code appelle 'close' avant de terminer le traitement de l'événement' EPOLLHUP'. Notez que 'EPOLLHUP' indique que l'autre partie a fermé la connexion - mais votre code n'a pas encore fermé la connexion. Puisque le 'fd' est toujours ouvert de votre côté,' epoll' continuera de l'interroger. – Myst
@myst Lorsque j'essaie de le fermer, il échoue avec un mauvais descripteur de fichier, dans ce cas. Mais merci pour la recommandation pour le cas général. –
Je suis certain que le client 'fd' (pas le' g.epoll_fd') doit être fermé par votre code afin de libérer ses ressources. Votre code n'est pas un exemple complet, il y a donc une limite à ce que je peux examiner. Je ne suis pas sûr quel appel de fonction provoque le 'EBADFD' ou quelle valeur vous passez à' close'. En fait, je ne sais même pas où vous stockez la valeur 'fd' de l'événement. Vous pouvez le stocker dans l'événement, mais j'utilise parfois l'événement pour stocker un pointeur vers un objet qui contient les données 'fd' ainsi que d'autres informations ... et peut-être que l'erreur se produit parce que vous ne le stockez pas. Je ne peux pas le dire. – Myst