From db3db782afefd8b5949ebed8aacc01429eaa6161 Mon Sep 17 00:00:00 2001 From: cg82616424 Date: Tue, 9 Mar 2021 19:27:15 +0800 Subject: [PATCH] [core] Fixed SRT_EPOLL_IN epoll event loss problem (#1843) --- srtcore/core.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/srtcore/core.cpp b/srtcore/core.cpp index df40ef0d5..c2d4caedf 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -7554,13 +7554,27 @@ int CUDT::sendCtrlAck(CPacket& ctrlpkt, int size) } else { - if (m_config.bSynRecving) { - // signal a waiting "recv" call if there is any data available - CSync::lock_signal(m_RecvDataCond, m_RecvLock); + UniqueLock rdlock (m_RecvLock); + CSync rdcond (m_RecvDataCond, rdlock); + if (m_config.bSynRecving) + { + // signal a waiting "recv" call if there is any data available + rdcond.signal_locked(rdlock); + } + // acknowledge any waiting epolls to read + // fix SRT_EPOLL_IN event loss but rcvbuffer still have dataļ¼š + // 1. user call receive/receivemessage(about line number:6482) + // 2. after read/receive, if rcvbuffer is empty, will set SRT_EPOLL_IN event to false + // 3. but if we do not do some lock work here, will cause some sync problems between threads: + // (1) user thread: call receive/receivemessage + // (2) user thread: read data + // (3) user thread: no data in rcvbuffer, set SRT_EPOLL_IN event to false + // (4) receive thread: receive data and set SRT_EPOLL_IN to true + // (5) user thread: set SRT_EPOLL_IN to false + // 4. so , m_RecvLock must be used here to protect epoll event + s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, SRT_EPOLL_IN, true); } - // acknowledge any waiting epolls to read - s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, SRT_EPOLL_IN, true); #if ENABLE_EXPERIMENTAL_BONDING if (m_parent->m_GroupOf) {