0
得到所以我有一些代碼,看起來像這樣:epoll_wait似乎停留在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...
}
}
}
一個單一的插座將被陷在EPOLLRDHUP || EPOLLHUP
情況。當我嘗試關閉它或執行EPOLL_CTL_DEL時,套接字可能會關閉,我得到一個EBADFD。這是我的理解,epoll會自動消除任何死亡的套接字,但這似乎並非如此......任何想法?
另一個可能的問題是,在套接字上我使用的是recvmsg/sendmsg,而且我正在通過這些套接字(它們是unix域流套接字)在進程之間發送文件描述符。我試圖做一個最後的recvmsg,但也失敗了......任何想法?
我建議您的代碼在完成處理「EPOLLHUP」事件之前調用'close'。請注意,'EPOLLHUP'表示對方已關閉連接 - 但您的代碼尚未關閉連接。由於'fd'仍然打開,'epoll'將繼續輪詢它。 – Myst
@myst當我嘗試關閉它時,在這種情況下,它會以錯誤的文件描述符失敗。但是,感謝您對一般情況的建議。 –
我確定你的代碼必須關閉客戶端'fd'(而不是'g.epoll_fd')才能釋放它的資源。你的代碼並不是一個完整的例子,所以我可以評論多少。我不確定哪個函數調用會導致'EBADFD'或者你傳遞給'close'的值。事實上,我甚至不確定你存儲事件的'fd'值的位置。您可以將它存儲在事件中,但我有時會使用該事件來存儲指向包含「fd」數據以及其他信息的對象的指針......並且可能會因爲您沒有將其存儲在任何地方而發生錯誤。我不知道。 – Myst