UDT中epoll對CLOSE狀態的處理

2022-03-07 17:55:13 字數 2144 閱讀 3752

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...