epoll_wait()返回可用uid時,對uid取狀態,本該是broken的,卻取到closed,然而,不能像處理broken事件那樣處理closed事件,這樣移除不了closed事件,於是epoll_wait不斷返回該uid,就造成了死迴圈。跟蹤**至底層,尋找原因。
int cudtunited::epoll_remove_usock(const int eid, const udtsocket u)
//else
//return ret;
}cudtsocket* cudtunited::locate(const udtsocket u)
void cudt::removeepoll(const int eid)
cudtunited::epoll_remove_usock裡,先locate目前uid的位置,但如果此時uid的狀態是closed,則返回null, 於是,epoll_remove_usock無法再繼續呼叫removeepoll,所以無法移除epoll事件。
但為什麼會發生closed事件呢?按照作者的原意,應該是只會發生broken事件,不會發生closed事件的,繼續查詢原因。
首先看看broken事件怎麼發生的。
客戶端疑似斷開十秒以上之後, cudt::checktimers()做以下操作
…………
m_bclosing = true;
m_bbroken = true;
m_ibrokencounter = 30;
// update snd u list to remove this socket
m_psndqueue->m_psndulist->update(this);
releasesynch();
s_udtunited.m_epoll.update_events(m_socketid, m_spollid, udt_epoll_in | udt_epoll_out | udt_epoll_err, true);
ctimer::triggerevent();
…………
在這裡把m_bbroken置為true,並觸發epoll事件。
然而,在epoll_wait返回事件之前,還可能發生這個:
#ifndef win32
void* cudtunited::garbagecollect(void* p)
#else
dword winapi cudtunited::garbagecollect(lpvoid p)
#endif
else if ((i->second->m_pudt->m_prcvbuffer != null) && (i->second->m_pudt->m_prcvbuffer->getrcvdatasize() > 0) && (i->second->m_pudt->m_ibrokencounter -- > 0))
//close broken connections and start removal timer
i->second->m_status = closed;
i->second->m_timestamp = ctimer::gettime();
tbc.push_back(i->first);
m_closedsockets[i->first] = i->second;
…………
gc執行緒是udt的垃圾**處理,在udt呼叫cleanup(),之前,會一直處於checkbrokensocket和阻塞的迴圈中。
然後在checkbrokensocket裡,當socket的m_bbroken為true時,m_status的狀態被置為closed。
所以,這時候再用getsocketstate取socket的狀態,就會取到closed,也就是明明是broken事件,硬生生變成了closed事件!然後接下去epoll事件的移除就失敗了。
於是,修改如下,
把int cepoll::remove_usock(const int eid, const udtsocket& u)
改為int cepoll::remove_usock2(const int eid, const udtsocket& u)
並去掉cudtunited::epoll_remove_usock()中對removeepoll()的呼叫。
這是比較簡單也比較粗糙的改法,應該有更方便的思路才對。
UDT中epoll對CLOSE狀態的處理
epoll wait 返回可用uid時,對uid取狀態,本該是broken的,卻取到closed,然而,不能像處理broken事件那樣處理closed事件,這樣移除不了closed事件,於是epoll wait不斷返回該uid,就造成了死迴圈。跟蹤 至底層,尋找原因。int cudtunited e...
linux程式設計中close與shutdown的區別
1.close 函式 cpp view plain copy print?font size 13px include intclose intsockfd 返回成功為0,出錯為 1.close 乙個套接字的預設行為是把套接字標記為已關閉,然後立即返回到呼叫程序,該套接字描述符不能再由呼叫程序使用,...
qt中destroyed和close視窗有什麼區別
qt的assistant中關於destroyed只有qobject類的該訊號,其中說的很清楚 物件被destroyed前將立即傳送該訊號,其不能夠被阻塞。該物件的所有子物件在訊號傳送以後會被立即銷毀。而qwidget與qwindow差不多都是釋放視窗相關資源。qwidget的close槽函式是像wi...