From c12e6198b0cbf6dc8759fe87f533e15111f245dc Mon Sep 17 00:00:00 2001 From: Sektor van Skijlen Date: Fri, 18 Dec 2020 10:03:39 +0100 Subject: [PATCH] [core] Refactored member pointer: now raw pointer to socket data (#1696) --- srtcore/api.cpp | 102 +++++++++++++++--------------- srtcore/api.h | 11 ++-- srtcore/core.cpp | 154 +++++++++++++++++++++++----------------------- srtcore/group.cpp | 58 ++++++++--------- srtcore/group.h | 28 ++++----- 5 files changed, 175 insertions(+), 178 deletions(-) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 2e9c4014b..5d0aa2904 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -86,8 +86,8 @@ extern LogConfig srt_logger_config; void CUDTSocket::construct() { #if ENABLE_EXPERIMENTAL_BONDING - m_IncludedGroup = NULL; - m_IncludedIter = CUDTGroup::gli_NULL(); + m_GroupOf = NULL; + m_GroupMemberData = NULL; #endif setupMutex(m_AcceptLock, "Accept"); setupCond(m_AcceptCond, "Accept"); @@ -677,16 +677,16 @@ int CUDTUnited::newConnection(const SRTSOCKET listen, const sockaddr_any& peer, error = 2; } - // The access to m_IncludedGroup should be also protected, as the group + // The access to m_GroupOf should be also protected, as the group // could be requested deletion in the meantime. This will hold any possible - // removal from group and resetting m_IncludedGroup field. + // removal from group and resetting m_GroupOf field. #if ENABLE_EXPERIMENTAL_BONDING - if (ns->m_IncludedGroup) + if (ns->m_GroupOf) { // XXX this might require another check of group type. // For redundancy group, at least, update the status in the group - CUDTGroup* g = ns->m_IncludedGroup; + CUDTGroup* g = ns->m_GroupOf; ScopedLock glock (g->m_GroupLock); if (g->m_bClosing) { @@ -694,13 +694,11 @@ int CUDTUnited::newConnection(const SRTSOCKET listen, const sockaddr_any& peer, goto ERR_ROLLBACK; } - CUDTGroup::gli_t gi; - // Check if this is the first socket in the group. // If so, give it up to accept, otherwise just do nothing // The client will be informed about the newly added connection at the // first moment when attempting to get the group status. - for (gi = g->m_Group.begin(); gi != g->m_Group.end(); ++gi) + for (CUDTGroup::gli_t gi = g->m_Group.begin(); gi != g->m_Group.end(); ++gi) { if (gi->laststatus == SRTS_CONNECTED) { @@ -713,13 +711,13 @@ int CUDTUnited::newConnection(const SRTSOCKET listen, const sockaddr_any& peer, // Update the status in the group so that the next // operation can include the socket in the group operation. - gi = ns->m_IncludedIter; + CUDTGroup::SocketData* gm = ns->m_GroupMemberData; HLOGC(cnlog.Debug, log << "newConnection(GROUP): Socket @" << ns->m_SocketID << " BELONGS TO $" << g->id() << " - will " << (should_submit_to_accept? "" : "NOT ") << "report in accept"); - gi->sndstate = SRT_GST_IDLE; - gi->rcvstate = SRT_GST_IDLE; - gi->laststatus = SRTS_CONNECTED; + gm->sndstate = SRT_GST_IDLE; + gm->rcvstate = SRT_GST_IDLE; + gm->laststatus = SRTS_CONNECTED; if (!g->m_bConnected) { @@ -845,9 +843,9 @@ int CUDTUnited::newConnection(const SRTSOCKET listen, const sockaddr_any& peer, ScopedLock cg(m_GlobControlLock); #if ENABLE_EXPERIMENTAL_BONDING - if (ns->m_IncludedGroup) + if (ns->m_GroupOf) { - HLOGC(smlog.Debug, log << "@" << ns->m_SocketID << " IS MEMBER OF $" << ns->m_IncludedGroup->id() << " - REMOVING FROM GROUP"); + HLOGC(smlog.Debug, log << "@" << ns->m_SocketID << " IS MEMBER OF $" << ns->m_GroupOf->id() << " - REMOVING FROM GROUP"); ns->removeFromGroup(true); } #endif @@ -1178,16 +1176,16 @@ SRTSOCKET CUDTUnited::accept(const SRTSOCKET listen, sockaddr* pw_addr, int* pw_ // and the already accepted socket has successfully joined // the mirror group. If so, RETURN THE GROUP ID, not the socket ID. #if ENABLE_EXPERIMENTAL_BONDING - if (ls->m_pUDT->m_OPT_GroupConnect == 1 && s->m_IncludedGroup) + if (ls->m_pUDT->m_OPT_GroupConnect == 1 && s->m_GroupOf) { // Put a lock to protect the group against accidental deletion // in the meantime. ScopedLock glock (m_GlobControlLock); // Check again; it's unlikely to happen, but // it's a theoretically possible scenario - if (s->m_IncludedGroup) + if (s->m_GroupOf) { - u = s->m_IncludedGroup->m_GroupID; + u = s->m_GroupOf->m_GroupID; s->core().m_OPT_GroupConnect = 1; // should be derived from ls, but make sure } else @@ -1495,9 +1493,9 @@ int CUDTUnited::groupConnect(CUDTGroup* pg, SRT_SOCKGROUPCONFIG* targets, int ar if (proceed) { - CUDTGroup::gli_t f = g.add(data); - ns->m_IncludedIter = f; - ns->m_IncludedGroup = &g; + CUDTGroup::SocketData* f = g.add(data); + ns->m_GroupMemberData = f; + ns->m_GroupOf = &g; f->weight = targets[tii].weight; LOGC(aclog.Note, log << "srt_connect_group: socket @" << sid << " added to group $" << g.m_GroupID); } @@ -1608,7 +1606,7 @@ int CUDTUnited::groupConnect(CUDTGroup* pg, SRT_SOCKGROUPCONFIG* targets, int ar // set busy, so it won't be deleted, even if it was requested to be closed. ScopedLock grd (g.m_GroupLock); - if (!ns->m_IncludedGroup) + if (!ns->m_GroupOf) { // The situation could get changed between the unlock and lock of m_GroupLock. // This must be checked again. @@ -1621,8 +1619,8 @@ int CUDTUnited::groupConnect(CUDTGroup* pg, SRT_SOCKGROUPCONFIG* targets, int ar continue; } - // If m_IncludedGroup is not NULL, the m_IncludedIter is still valid. - CUDTGroup::gli_t f = ns->m_IncludedIter; + // If m_GroupOf is not NULL, the m_IncludedIter is still valid. + CUDTGroup::SocketData* f = ns->m_GroupMemberData; // Now under a group lock, we need to make sure the group isn't being closed // in order not to add a socket to a dead group. @@ -1957,11 +1955,11 @@ void CUDTUnited::deleteGroup(CUDTGroup* g) i != m_Sockets.end(); ++ i) { CUDTSocket* s = i->second; - if (s->m_IncludedGroup == g) + if (s->m_GroupOf == g) { HLOGC(smlog.Debug, log << "deleteGroup: IPE: existing @" << s->m_SocketID << " points to a dead group!"); - s->m_IncludedGroup = NULL; - s->m_IncludedIter = CUDTGroup::gli_NULL(); + s->m_GroupOf = NULL; + s->m_GroupMemberData = NULL; } } @@ -1971,11 +1969,11 @@ void CUDTUnited::deleteGroup(CUDTGroup* g) i != m_ClosedSockets.end(); ++ i) { CUDTSocket* s = i->second; - if (s->m_IncludedGroup == g) + if (s->m_GroupOf == g) { HLOGC(smlog.Debug, log << "deleteGroup: IPE: closed @" << s->m_SocketID << " points to a dead group!"); - s->m_IncludedGroup = NULL; - s->m_IncludedIter = CUDTGroup::gli_NULL(); + s->m_GroupOf = NULL; + s->m_GroupMemberData = NULL; } } } @@ -2048,9 +2046,9 @@ int CUDTUnited::close(CUDTSocket* s) s->setClosed(); #if ENABLE_EXPERIMENTAL_BONDING - if (s->m_IncludedGroup) + if (s->m_GroupOf) { - HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_IncludedGroup->id() << " - REMOVING FROM GROUP"); + HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_GroupOf->id() << " - REMOVING FROM GROUP"); s->removeFromGroup(true); } #endif @@ -2563,7 +2561,7 @@ CUDTGroup* CUDTUnited::locateAcquireGroup(SRTSOCKET u, ErrorHandling erh) CUDTGroup* CUDTUnited::acquireSocketsGroup(CUDTSocket* s) { ScopedLock cg (m_GlobControlLock); - CUDTGroup* g = s->m_IncludedGroup; + CUDTGroup* g = s->m_GroupOf; if (!g) return NULL; @@ -2672,9 +2670,9 @@ void CUDTUnited::checkBrokenSockets() } #if ENABLE_EXPERIMENTAL_BONDING - if (s->m_IncludedGroup) + if (s->m_GroupOf) { - LOGC(smlog.Note, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_IncludedGroup->id() << " - REMOVING FROM GROUP"); + LOGC(smlog.Note, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_GroupOf->id() << " - REMOVING FROM GROUP"); s->removeFromGroup(true); } #endif @@ -2757,9 +2755,9 @@ void CUDTUnited::removeSocket(const SRTSOCKET u) CUDTSocket* const s = i->second; #if ENABLE_EXPERIMENTAL_BONDING - if (s->m_IncludedGroup) + if (s->m_GroupOf) { - HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_IncludedGroup->id() << " - REMOVING FROM GROUP"); + HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_GroupOf->id() << " - REMOVING FROM GROUP"); s->removeFromGroup(true); } #endif @@ -3101,9 +3099,9 @@ void* CUDTUnited::garbageCollect(void* p) s->breakSocket_LOCKED(); #if ENABLE_EXPERIMENTAL_BONDING - if (s->m_IncludedGroup) + if (s->m_GroupOf) { - HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_IncludedGroup->id() << " (IPE?) - REMOVING FROM GROUP"); + HLOGC(smlog.Debug, log << "@" << s->m_SocketID << " IS MEMBER OF $" << s->m_GroupOf->id() << " (IPE?) - REMOVING FROM GROUP"); s->removeFromGroup(false); } #endif @@ -3262,7 +3260,7 @@ int CUDT::addSocketToGroup(SRTSOCKET socket, SRTSOCKET group) return APIError(MJ_NOTSUP, MN_INVAL, 0); // Check if the socket is already IN SOME GROUP. - if (s->m_IncludedGroup) + if (s->m_GroupOf) return APIError(MJ_NOTSUP, MN_INVAL, 0); CUDTGroup* g = k.group; @@ -3282,17 +3280,17 @@ int CUDT::addSocketToGroup(SRTSOCKET socket, SRTSOCKET group) return APIError(MJ_NOTSUP, MN_INVAL, 0); // Check if the socket already is in the group - CUDTGroup::gli_t f = g->find(socket); - if (f != CUDTGroup::gli_NULL()) + CUDTGroup::SocketData* f; + if (g->contains(socket, (f))) { // XXX This is internal error. Report it, but continue LOGC(aclog.Error, log << "IPE (non-fatal): the socket is in the group, but has no clue about it!"); - s->m_IncludedIter = f; - s->m_IncludedGroup = g; + s->m_GroupMemberData = f; + s->m_GroupOf = g; return 0; } - s->m_IncludedIter = g->add(g->prepareData(s)); - s->m_IncludedGroup = g; + s->m_GroupMemberData = g->add(g->prepareData(s)); + s->m_GroupOf = g; return 0; } @@ -3305,7 +3303,7 @@ int CUDT::removeSocketFromGroup(SRTSOCKET socket) if (!s) return APIError(MJ_NOTSUP, MN_INVAL, 0); - if (!s->m_IncludedGroup) + if (!s->m_GroupOf) return APIError(MJ_NOTSUP, MN_INVAL, 0); ScopedLock cg (s->m_ControlLock); @@ -3318,7 +3316,7 @@ int CUDT::removeSocketFromGroup(SRTSOCKET socket) // [[using locked(CUDT::s_UDTUnited.m_GlobControlLock)]] void CUDTSocket::removeFromGroup(bool broken) { - CUDTGroup* g = m_IncludedGroup; + CUDTGroup* g = m_GroupOf; if (g) { // Reset group-related fields immediately. They won't be accessed @@ -3326,8 +3324,8 @@ void CUDTSocket::removeFromGroup(bool broken) // a short moment between removal from the group container and the end, // while the GroupLock would be already taken out. It is safer to reset // it to a NULL iterator before removal. - m_IncludedGroup = NULL; - m_IncludedIter = CUDTGroup::gli_NULL(); + m_GroupOf = NULL; + m_GroupMemberData = NULL; bool still_have = g->remove(m_SocketID); if (broken) @@ -3351,10 +3349,10 @@ SRTSOCKET CUDT::getGroupOfSocket(SRTSOCKET socket) // to persist the call. ScopedLock glock (s_UDTUnited.m_GlobControlLock); CUDTSocket* s = s_UDTUnited.locateSocket_LOCKED(socket); - if (!s || !s->m_IncludedGroup) + if (!s || !s->m_GroupOf) return APIError(MJ_NOTSUP, MN_INVAL, 0); - return s->m_IncludedGroup->id(); + return s->m_GroupOf->id(); } int CUDT::configureGroup(SRTSOCKET groupid, const char* str) diff --git a/srtcore/api.h b/srtcore/api.h index 8ad6bb3fd..fa18a6bba 100644 --- a/srtcore/api.h +++ b/srtcore/api.h @@ -83,7 +83,8 @@ class CUDTSocket , m_ListenSocket(0) , m_PeerID(0) #if ENABLE_EXPERIMENTAL_BONDING - , m_IncludedGroup() + , m_GroupMemberData() + , m_GroupOf() #endif , m_iISN(0) , m_pUDT(NULL) @@ -110,16 +111,16 @@ class CUDTSocket /// 1 second (see CUDTUnited::checkBrokenSockets()). srt::sync::steady_clock::time_point m_tsClosureTimeStamp; - sockaddr_any m_SelfAddr; //< local address of the socket - sockaddr_any m_PeerAddr; //< peer address of the socket + sockaddr_any m_SelfAddr; //< local address of the socket + sockaddr_any m_PeerAddr; //< peer address of the socket SRTSOCKET m_SocketID; //< socket ID SRTSOCKET m_ListenSocket; //< ID of the listener socket; 0 means this is an independent socket SRTSOCKET m_PeerID; //< peer socket ID #if ENABLE_EXPERIMENTAL_BONDING - CUDTGroup::gli_t m_IncludedIter; //< Container's iterator of the group to which it belongs, or gli_NULL() if it isn't - CUDTGroup* m_IncludedGroup; //< Group this socket is a member of, or NULL if it isn't + CUDTGroup::SocketData* m_GroupMemberData; //< Pointer to group member data, or NULL if not a group member + CUDTGroup* m_GroupOf; //< Group this socket is a member of, or NULL if it isn't #endif int32_t m_iISN; //< initial sequence number, used to tell different connection from same IP:port diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 714b8a163..38a492e6e 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -1882,17 +1882,17 @@ size_t CUDT::fillHsExtConfigString(uint32_t* pcmdspec, int cmd, const string& st // [[using locked(s_UDTUnited.m_GlobControlLock)]] size_t CUDT::fillHsExtGroup(uint32_t* pcmdspec) { - SRT_ASSERT(m_parent->m_IncludedGroup != NULL); + SRT_ASSERT(m_parent->m_GroupOf != NULL); uint32_t* space = pcmdspec + 1; - SRTSOCKET id = m_parent->m_IncludedGroup->id(); - SRT_GROUP_TYPE tp = m_parent->m_IncludedGroup->type(); + SRTSOCKET id = m_parent->m_GroupOf->id(); + SRT_GROUP_TYPE tp = m_parent->m_GroupOf->type(); uint32_t flags = 0; // Note: if agent is a listener, and the current version supports // both sync methods, this flag might have been changed according to // the wish of the caller. - if (m_parent->m_IncludedGroup->synconmsgno()) + if (m_parent->m_GroupOf->synconmsgno()) flags |= SRT_GFLAG_SYNCONMSG; // NOTE: this code remains as is for historical reasons. @@ -1902,7 +1902,7 @@ size_t CUDT::fillHsExtGroup(uint32_t* pcmdspec) // extension, but it was later seen not necessary. Therefore // this code remains, but now it's informational only. #if ENABLE_HEAVY_LOGGING - m_parent->m_IncludedGroup->debugMasterData(m_SocketID); + m_parent->m_GroupOf->debugMasterData(m_SocketID); #endif // See CUDT::interpretGroup() @@ -1910,7 +1910,7 @@ size_t CUDT::fillHsExtGroup(uint32_t* pcmdspec) uint32_t dataword = 0 | SrtHSRequest::HS_GROUP_TYPE::wrap(tp) | SrtHSRequest::HS_GROUP_FLAGS::wrap(flags) - | SrtHSRequest::HS_GROUP_WEIGHT::wrap(m_parent->m_IncludedIter->weight); + | SrtHSRequest::HS_GROUP_WEIGHT::wrap(m_parent->m_GroupMemberData->weight); const uint32_t storedata [GRPD_E_SIZE] = { uint32_t(id), dataword }; memcpy((space), storedata, sizeof storedata); @@ -2193,7 +2193,7 @@ bool CUDT::createSrtHandshake( // hurt, even if this field could be dangling in the moment. This will be // followed by an additional check, done this time under lock, and there will // be no dangling pointers at this time. - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // Whatever group this socket belongs to, the information about // the group is always sent the same way with the handshake. @@ -2303,9 +2303,9 @@ bool CUDT::createSrtHandshake( // NOTE: See information about mutex ordering in api.h ScopedLock grd (m_parent->m_ControlLock); // Required to make sure ScopedLock gdrg (s_UDTUnited.m_GlobControlLock); - if (!m_parent->m_IncludedGroup) + if (!m_parent->m_GroupOf) { - // This may only happen if since last check of m_IncludedGroup pointer the socket was removed + // This may only happen if since last check of m_GroupOf pointer the socket was removed // from the group in the meantime, which can only happen due to that the group was closed. // In such a case it simply means that the handshake process was requested to be interrupted. LOGC(cnlog.Fatal, log << "GROUP DISAPPEARED. Socket not capable of continuing HS"); @@ -2313,7 +2313,7 @@ bool CUDT::createSrtHandshake( } else { - if (m_parent->m_IncludedGroup->closing()) + if (m_parent->m_GroupOf->closing()) { m_RejectReason = SRT_REJ_IPE; LOGC(cnlog.Error, log << "createSrtHandshake: group is closing during the process, rejecting."); @@ -3390,9 +3390,9 @@ bool CUDT::interpretSrtHandshake(const CHandShake& hs, } #if ENABLE_EXPERIMENTAL_BONDING - // m_IncludedGroup and locking info: NULL check won't hurt here. If the group + // m_GroupOf and locking info: NULL check won't hurt here. If the group // was deleted in the meantime, it will be found out later anyway and result with error. - if (m_SrtHsSide == HSD_INITIATOR && m_parent->m_IncludedGroup) + if (m_SrtHsSide == HSD_INITIATOR && m_parent->m_GroupOf) { // XXX Later probably needs to check if this group REQUIRES the group // response. Currently this implements the bonding-category group, and this @@ -3567,7 +3567,7 @@ bool CUDT::interpretGroup(const int32_t groupdata[], size_t data_size SRT_ATR_UN // the same id, otherwise the connection should be rejected. // So, first check the group of the current socket and see if a peer is set. - CUDTGroup* pg = m_parent->m_IncludedGroup; + CUDTGroup* pg = m_parent->m_GroupOf; if (!pg) { // This means that the responder has responded with a group membership, @@ -3630,7 +3630,7 @@ bool CUDT::interpretGroup(const int32_t groupdata[], size_t data_size SRT_ATR_UN return false; // error occurred } - if (!m_parent->m_IncludedGroup) + if (!m_parent->m_GroupOf) { // Strange, we just added it... m_RejectReason = SRT_REJ_IPE; @@ -3638,14 +3638,14 @@ bool CUDT::interpretGroup(const int32_t groupdata[], size_t data_size SRT_ATR_UN return false; } - CUDTGroup::gli_t f = m_parent->m_IncludedIter; + CUDTGroup::SocketData* f = m_parent->m_GroupMemberData; f->weight = link_weight; f->agent = m_parent->m_SelfAddr; f->peer = m_PeerAddr; } - m_parent->m_IncludedGroup->debugGroup(); + m_parent->m_GroupOf->debugGroup(); // That's all. For specific things concerning group // types, this will be later. @@ -3737,19 +3737,19 @@ SRTSOCKET CUDT::makeMePeerOf(SRTSOCKET peergroup, SRT_GROUP_TYPE gtp, uint32_t l // Copy of addSocketToGroup. No idea how many parts could be common, not much. // Check if the socket already is in the group - CUDTGroup::gli_t f = gp->find(m_SocketID); - if (f != CUDTGroup::gli_NULL()) + CUDTGroup::SocketData* f; + if (gp->contains(m_SocketID, (f))) { // XXX This is internal error. Report it, but continue // (A newly created socket from acceptAndRespond should not have any group membership yet) LOGC(gmlog.Error, log << "IPE (non-fatal): the socket is in the group, but has no clue about it!"); - s->m_IncludedGroup = gp; - s->m_IncludedIter = f; + s->m_GroupOf = gp; + s->m_GroupMemberData = f; return 0; } - s->m_IncludedIter = gp->add(gp->prepareData(s)); - s->m_IncludedGroup = gp; + s->m_GroupMemberData = gp->add(gp->prepareData(s)); + s->m_GroupOf = gp; // Record the remote address in the group data. @@ -5032,7 +5032,7 @@ EConnectStatus CUDT::postConnect(const CPacket &response, bool rendezvous, CUDTE { #if ENABLE_EXPERIMENTAL_BONDING ScopedLock cl (s_UDTUnited.m_GlobControlLock); - CUDTGroup* g = m_parent->m_IncludedGroup; + CUDTGroup* g = m_parent->m_GroupOf; if (g) { // This is the last moment when this can be done. @@ -5133,7 +5133,7 @@ EConnectStatus CUDT::postConnect(const CPacket &response, bool rendezvous, CUDTE #if ENABLE_EXPERIMENTAL_BONDING { ScopedLock cl (s_UDTUnited.m_GlobControlLock); - CUDTGroup* g = m_parent->m_IncludedGroup; + CUDTGroup* g = m_parent->m_GroupOf; if (g) { // XXX this might require another check of group type. @@ -5142,13 +5142,13 @@ EConnectStatus CUDT::postConnect(const CPacket &response, bool rendezvous, CUDTE // LEAVING as comment for historical reasons. Locking is here most // likely not necessary because the socket cannot be removed from the // group until the socket isn't removed, and this requires locking of - // m_GlobControlLock. This should ensure that when m_IncludedGroup is - // not NULL, m_IncludedIter is also valid. + // m_GlobControlLock. This should ensure that when m_GroupOf is + // not NULL, m_GroupMemberData is also valid. // ScopedLock glock(g->m_GroupLock); HLOGC(cnlog.Debug, log << "group: Socket @" << m_parent->m_SocketID << " fresh connected, setting IDLE"); - CUDTGroup::gli_t gi = m_parent->m_IncludedIter; + CUDTGroup::SocketData* gi = m_parent->m_GroupMemberData; gi->sndstate = SRT_GST_IDLE; gi->rcvstate = SRT_GST_IDLE; gi->laststatus = SRTS_CONNECTED; @@ -5743,7 +5743,7 @@ void *CUDT::tsbpd(void *param) // the next CUDTGroup::recv() call should return with no blocking or not. // When the group is read-ready, it should update its pollers as it sees fit. - // NOTE: this call will set lock to m_IncludedGroup->m_GroupLock + // NOTE: this call will set lock to m_GroupOf->m_GroupLock HLOGC(tslog.Debug, log << self->CONID() << "tsbpd: GROUP: checking if %" << current_pkt_seq << " makes group readable"); gkeeper.group->updateReadState(self->m_SocketID, current_pkt_seq); @@ -5986,7 +5986,7 @@ void CUDT::acceptAndRespond(const sockaddr_any& agent, const sockaddr_any& peer, { #if ENABLE_EXPERIMENTAL_BONDING ScopedLock cl (s_UDTUnited.m_GlobControlLock); - CUDTGroup* g = m_parent->m_IncludedGroup; + CUDTGroup* g = m_parent->m_GroupOf; if (g) { // This is the last moment when this can be done. @@ -6558,7 +6558,7 @@ int CUDT::receiveBuffer(char *data, int len) return res; } -// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_IncludedGroup != NULL)]]; +// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_GroupOf != NULL)]]; // [[using locked(m_SendLock)]]; void CUDT::checkNeedDrop(bool& w_bCongestion) { @@ -6638,9 +6638,9 @@ void CUDT::checkNeedDrop(bool& w_bCongestion) // What's important is that the lock on GroupLock cannot be applied // here, both because it might be applied already, and because the // locks on the later lock ordered mutexes are already set. - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { - m_parent->m_IncludedGroup->ackMessage(first_msgno); + m_parent->m_GroupOf->ackMessage(first_msgno); } #endif } @@ -6665,9 +6665,9 @@ int CUDT::sendmsg(const char *data, int len, int msttl, bool inorder, int64_t sr return this->sendmsg2(data, len, (mctrl)); } -// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_IncludedGroup != NULL)]] +// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_GroupOf != NULL)]] // GroupLock is applied when this function is called from inside CUDTGroup::send, -// which is the only case when the m_parent->m_IncludedGroup is not NULL. +// which is the only case when the m_parent->m_GroupOf is not NULL. int CUDT::sendmsg2(const char *data, int len, SRT_MSGCTRL& w_mctrl) { bool bCongestion = false; @@ -6959,16 +6959,16 @@ int CUDT::recvmsg(char* data, int len, int64_t& srctime) return res; } -// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_IncludedGroup != NULL)]] +// [[using maybe_locked(CUDTGroup::m_GroupLock, m_parent->m_GroupOf != NULL)]] // GroupLock is applied when this function is called from inside CUDTGroup::recv, -// which is the only case when the m_parent->m_IncludedGroup is not NULL. +// which is the only case when the m_parent->m_GroupOf is not NULL. int CUDT::recvmsg2(char* data, int len, SRT_MSGCTRL& w_mctrl) { // Check if the socket is a member of a receiver group. // If so, then reading by receiveMessage is disallowed. #if ENABLE_EXPERIMENTAL_BONDING - if (m_parent->m_IncludedGroup && m_parent->m_IncludedGroup->isGroupReceiver()) + if (m_parent->m_GroupOf && m_parent->m_GroupOf->isGroupReceiver()) { LOGP(arlog.Error, "recv*: This socket is a receiver group member. Use group ID, NOT socket ID."); throw CUDTException(MJ_NOTSUP, MN_INVALMSGAPI, 0); @@ -8139,7 +8139,7 @@ int CUDT::sendCtrlAck(CPacket& ctrlpkt, int size) // required in the defined order. At present we only need the lock // on m_GlobControlLock to prevent the group from being deleted // in the meantime - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // Check is first done before locking to avoid unnecessary // mutex locking. The condition for this field is that it @@ -8148,14 +8148,14 @@ int CUDT::sendCtrlAck(CPacket& ctrlpkt, int size) // the dangling case. ScopedLock glock (s_UDTUnited.m_GlobControlLock); - // Note that updateLatestRcv will lock m_IncludedGroup->m_GroupLock, + // Note that updateLatestRcv will lock m_GroupOf->m_GroupLock, // but this is an intended order. - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // A group may need to update the parallelly used idle links, // should it have any. Pass the current socket position in order // to skip it from the group loop. - m_parent->m_IncludedGroup->updateLatestRcv(m_parent); + m_parent->m_GroupOf->updateLatestRcv(m_parent); } } #endif @@ -8187,17 +8187,17 @@ int CUDT::sendCtrlAck(CPacket& ctrlpkt, int size) // 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_IncludedGroup) + if (m_parent->m_GroupOf) { // See above explanation for double-checking ScopedLock glock (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // The current "APP reader" needs to simply decide as to whether // the next CUDTGroup::recv() call should return with no blocking or not. // When the group is read-ready, it should update its pollers as it sees fit. - m_parent->m_IncludedGroup->updateReadState(m_SocketID, first_seq); + m_parent->m_GroupOf->updateReadState(m_SocketID, first_seq); } } #endif @@ -8304,7 +8304,7 @@ void CUDT::updateSndLossListOnACK(int32_t ackdata_seqno) // This is for the call of CSndBuffer::getMsgNoAt that returns // this value as a notfound-trap. int32_t msgno_at_last_acked_seq = SRT_MSGNO_CONTROL; - bool is_group = m_parent->m_IncludedGroup; + bool is_group = m_parent->m_GroupOf; #endif // Update sender's loss list and acknowledge packets in the sender's buffer @@ -8350,12 +8350,12 @@ void CUDT::updateSndLossListOnACK(int32_t ackdata_seqno) // m_RecvAckLock is ordered AFTER m_GlobControlLock, so this can only // be done now that m_RecvAckLock is unlocked. ScopedLock glock (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { HLOGC(xtlog.Debug, log << "ACK: acking group sender buffer for #" << msgno_at_last_acked_seq); // NOTE: ackMessage also accepts and ignores the trap representation // which is SRT_MSGNO_CONTROL. - m_parent->m_IncludedGroup->ackMessage(msgno_at_last_acked_seq); + m_parent->m_GroupOf->ackMessage(msgno_at_last_acked_seq); } } #endif @@ -8488,14 +8488,14 @@ void CUDT::processCtrlAck(const CPacket &ctrlpkt, const steady_clock::time_point // leaveCS(m_RecvAckLock); #if ENABLE_EXPERIMENTAL_BONDING - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { ScopedLock glock (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // Will apply m_GroupLock, ordered after m_GlobControlLock. // m_GlobControlLock is necessary for group existence. - m_parent->m_IncludedGroup->updateWriteState(); + m_parent->m_GroupOf->updateWriteState(); } } #endif @@ -8782,12 +8782,12 @@ void CUDT::processCtrl(const CPacket &ctrlpkt) const bool drift_updated ATR_UNUSED = m_pRcvBuffer->addRcvTsbPdDriftSample(ctrlpkt.getMsgTimeStamp(), m_RecvLock, (udrift), (newtimebase)); #if ENABLE_EXPERIMENTAL_BONDING - if (drift_updated && m_parent->m_IncludedGroup) + if (drift_updated && m_parent->m_GroupOf) { ScopedLock glock (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { - m_parent->m_IncludedGroup->synchronizeDrift(this, udrift, newtimebase); + m_parent->m_GroupOf->synchronizeDrift(this, udrift, newtimebase); } } #endif @@ -9107,11 +9107,11 @@ void CUDT::updateAfterSrtHandshake(int hsv) #if ENABLE_EXPERIMENTAL_BONDING string grpspec; - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { ScopedLock glock (s_UDTUnited.m_GlobControlLock); - grpspec = m_parent->m_IncludedGroup - ? " group=$" + Sprint(m_parent->m_IncludedGroup->id()) + grpspec = m_parent->m_GroupOf + ? " group=$" + Sprint(m_parent->m_GroupOf->id()) : string(); } #else @@ -9330,7 +9330,7 @@ std::pair CUDT::packData(CPacket& w_packet) // sequence is moved due to the difference between ISN caught during the existing // transmission and the first sequence possible to be used at the first sending // instruction. The group itself isn't being accessed. - if (m_parent->m_IncludedGroup && m_iSndCurrSeqNo != w_packet.m_iSeqNo && m_iSndCurrSeqNo == m_iISN) + if (m_parent->m_GroupOf && m_iSndCurrSeqNo != w_packet.m_iSeqNo && m_iSndCurrSeqNo == m_iISN) { const int packetspan = CSeqNo::seqcmp(w_packet.m_iSeqNo, m_iSndCurrSeqNo); @@ -9371,7 +9371,7 @@ std::pair CUDT::packData(CPacket& w_packet) << " STAMP:" << BufferStamp(w_packet.m_pcData, w_packet.getLength())); #if ENABLE_EXPERIMENTAL_BONDING - HLOGC(qslog.Debug, log << "... CONDITION: IN GROUP: " << (m_parent->m_IncludedGroup ? "yes":"no") + HLOGC(qslog.Debug, log << "... CONDITION: IN GROUP: " << (m_parent->m_GroupOf ? "yes":"no") << " extraction-seq=" << m_iSndCurrSeqNo << " scheduling-seq=" << w_packet.m_iSeqNo << " ISN=" << m_iISN); #endif @@ -9823,16 +9823,16 @@ int CUDT::processData(CUnit* in_unit) // accepted or rejected because if it was belated it may result in a // "runaway train" problem as the IDLE links are being updated the base // reception sequence pointer stating that this link is not receiving. - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { ScopedLock protect_group_existence (s_UDTUnited.m_GlobControlLock); - CUDTGroup::gli_t gi = m_parent->m_IncludedIter; + CUDTGroup::SocketData* gi = m_parent->m_GroupMemberData; // This check is needed as after getting the lock the socket // could be potentially removed. It is however granted that as long // as gi is non-NULL iterator, the group does exist and it does contain // this socket as member (that is, 'gi' cannot be a dangling iterator). - if (gi != CUDTGroup::gli_NULL()) + if (gi != NULL) { if (gi->rcvstate < SRT_GST_RUNNING) // PENDING or IDLE, tho PENDING is unlikely { @@ -10323,9 +10323,9 @@ CUDT::loss_seqs_t CUDT::defaultPacketArrival(void* vself, CPacket& pkt) // XXX When an alternative packet arrival callback is installed // in case of groups, move this part to the groupwise version. - if (self->m_parent->m_IncludedGroup) + if (self->m_parent->m_GroupOf) { - CUDTGroup::gli_t gi = self->m_parent->m_IncludedIter; + CUDTGroup::SocketData* gi = self->m_parent->m_GroupMemberData; if (gi->rcvstate < SRT_GST_RUNNING) // PENDING or IDLE, tho PENDING is unlikely { HLOGC(qrlog.Debug, log << "defaultPacketArrival: IN-GROUP rcv state transition to RUNNING. NOT checking for loss"); @@ -11257,15 +11257,15 @@ void CUDT::checkTimers() { sendCtrl(UMSG_KEEPALIVE); #if ENABLE_EXPERIMENTAL_BONDING - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { ScopedLock glock (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // Pass socket ID because it's about changing group socket data - m_parent->m_IncludedGroup->internalKeepalive(m_parent->m_IncludedIter); + m_parent->m_GroupOf->internalKeepalive(m_parent->m_GroupMemberData); // NOTE: GroupLock is unnecessary here because the only data read and - // modified is the target of the iterator from m_IncludedIter. The + // modified is the target of the iterator from m_GroupMemberData. The // iterator will be valid regardless of any container modifications. } } @@ -11290,21 +11290,21 @@ void CUDT::completeBrokenConnectionDependencies(int errorcode) bool pending_broken = false; { ScopedLock guard_group_existence (s_UDTUnited.m_GlobControlLock); - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { - token = m_parent->m_IncludedIter->token; - if (m_parent->m_IncludedIter->sndstate == SRT_GST_PENDING) + token = m_parent->m_GroupMemberData->token; + if (m_parent->m_GroupMemberData->sndstate == SRT_GST_PENDING) { HLOGC(gmlog.Debug, log << "updateBrokenConnection: a pending link was broken - will be removed"); pending_broken = true; } else { - HLOGC(gmlog.Debug, log << "updateBrokenConnection: state=" << CUDTGroup::StateStr(m_parent->m_IncludedIter->sndstate) << " a used link was broken - not closing automatically"); + HLOGC(gmlog.Debug, log << "updateBrokenConnection: state=" << CUDTGroup::StateStr(m_parent->m_GroupMemberData->sndstate) << " a used link was broken - not closing automatically"); } - m_parent->m_IncludedIter->sndstate = SRT_GST_BROKEN; - m_parent->m_IncludedIter->rcvstate = SRT_GST_BROKEN; + m_parent->m_GroupMemberData->sndstate = SRT_GST_BROKEN; + m_parent->m_GroupMemberData->rcvstate = SRT_GST_BROKEN; } } #endif @@ -11322,7 +11322,7 @@ void CUDT::completeBrokenConnectionDependencies(int errorcode) // the operation. The attempt of group deletion will // have to wait until this operation completes. ScopedLock lock(s_UDTUnited.m_GlobControlLock); - CUDTGroup* pg = m_parent->m_IncludedGroup; + CUDTGroup* pg = m_parent->m_GroupOf; if (pg) { // Bound to one call because this requires locking @@ -11564,7 +11564,7 @@ void CUDT::handleKeepalive(const char* /*data*/, size_t /*size*/) // for extra data sent through keepalive. #if ENABLE_EXPERIMENTAL_BONDING - if (m_parent->m_IncludedGroup) + if (m_parent->m_GroupOf) { // Lock GlobControlLock in order to make sure that // the state if the socket having the group and the @@ -11572,13 +11572,13 @@ void CUDT::handleKeepalive(const char* /*data*/, size_t /*size*/) // the operation. The attempt of group deletion will // have to wait until this operation completes. ScopedLock lock(s_UDTUnited.m_GlobControlLock); - CUDTGroup* pg = m_parent->m_IncludedGroup; + CUDTGroup* pg = m_parent->m_GroupOf; if (pg) { // Whether anything is to be done with this socket // about the fact that keepalive arrived, let the // group handle it - pg->handleKeepalive(m_parent->m_IncludedIter); + pg->handleKeepalive(m_parent->m_GroupMemberData); } } #endif diff --git a/srtcore/group.cpp b/srtcore/group.cpp index 13082e44b..fd5b480ff 100644 --- a/srtcore/group.cpp +++ b/srtcore/group.cpp @@ -211,9 +211,7 @@ void CUDTGroup::debugMasterData(SRTSOCKET slave) // GROUP -std::list CUDTGroup::GroupContainer::s_NoList; - -CUDTGroup::gli_t CUDTGroup::add(SocketData data) +CUDTGroup::SocketData* CUDTGroup::add(SocketData data) { ScopedLock g(m_GroupLock); @@ -242,7 +240,8 @@ CUDTGroup::gli_t CUDTGroup::add(SocketData data) m_iMaxPayloadSize = plsize; } - return --end; + --end; + return &*end; } CUDTGroup::SocketData CUDTGroup::prepareData(CUDTSocket* s) @@ -363,6 +362,7 @@ void CUDTGroup::GroupContainer::erase(CUDTGroup::gli_t it) if (m_List.empty()) { LOGC(gmlog.Error, log << "IPE: GroupContainer is empty and 'erase' is called on it."); + m_LastActiveLink = m_List.end(); return; // this avoids any misunderstandings in iterator checks } @@ -371,7 +371,7 @@ void CUDTGroup::GroupContainer::erase(CUDTGroup::gli_t it) if (bb == m_List.end()) // means: m_List.size() == 1 { // One element, this one being deleted, nothing to point to. - m_LastActiveLink = null(); + m_LastActiveLink = m_List.end(); } else { @@ -971,8 +971,8 @@ void CUDTGroup::close() HLOGC(smlog.Debug, log << "group/close: IPE(NF): group member @" << ig->id << " already deleted"); continue; } - s->m_IncludedGroup = NULL; - s->m_IncludedIter = gli_NULL(); + s->m_GroupOf = NULL; + s->m_GroupMemberData = NULL; HLOGC(smlog.Debug, log << "group/close: CUTTING OFF @" << ig->id << " (found as @" << s->m_SocketID << ") from the group"); } @@ -1257,7 +1257,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) curseq = w_mc.pktseq; } - const Sendstate cstate = {d->id, d, stat, erc}; + const Sendstate cstate = {d->id, &*d, stat, erc}; sendstates.push_back(cstate); d->sndresult = stat; d->laststatus = d->ps->getStatus(); @@ -1307,7 +1307,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) for (vector::iterator i = idlers.begin(); i != idlers.end(); ++i) { gli_t d = *i; - if (!d->ps->m_IncludedGroup) + if (!d->ps->m_GroupOf) continue; int erc = 0; @@ -1355,7 +1355,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) d->sndresult = stat; d->laststatus = d->ps->getStatus(); - const Sendstate cstate = {d->id, d, stat, erc}; + const Sendstate cstate = {d->id, &*d, stat, erc}; sendstates.push_back(cstate); } @@ -1452,7 +1452,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) // If there were only some reactivated idlers successful, the first // idler has defined the sequence. - vector successful, blocked; + vector successful, blocked; // This iteration of the state will simply // qualify the remaining sockets into three categories: @@ -1464,7 +1464,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) // Now - sendstates contain directly sockets. // In order to update members, you need to have locked: // - GlobControlLock to prevent sockets from disappearing or being closed - // - then GroupLock to latch the validity of m_IncludedIter field. + // - then GroupLock to latch the validity of m_GroupMemberData field. { { @@ -1486,11 +1486,11 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) // Is the socket still group member? If not, SKIP IT. It could only be taken ownership // by being explicitly closed and so it's deleted from the container. - if (!ps->m_IncludedGroup) + if (!ps->m_GroupOf) continue; - // Now we are certain that m_IncludedIter is valid. - gli_t d = ps->m_IncludedIter; + // Now we are certain that m_GroupMemberData is valid. + SocketData* d = ps->m_GroupMemberData; if (is->stat == len) { @@ -1542,7 +1542,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) // Good. All blocked links are now qualified as broken. // You had your chance, but I can't leave you here, // there will be no further chance to reattempt sending. - for (vector::iterator b = blocked.begin(); b != blocked.end(); ++b) + for (vector::iterator b = blocked.begin(); b != blocked.end(); ++b) { (*b)->sndstate = SRT_GST_BROKEN; } @@ -1573,7 +1573,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) // haven't sent the payload over any link so far, so we still have // a chance to retry. int modes = SRT_EPOLL_OUT | SRT_EPOLL_ERR; - for (vector::iterator b = blocked.begin(); b != blocked.end(); ++b) + for (vector::iterator b = blocked.begin(); b != blocked.end(); ++b) { HLOGC(gslog.Debug, log << "Will block on blocked socket @" << (*b)->id << " as only blocked socket remained"); @@ -1657,7 +1657,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) if (stat != -1) curseq = w_mc.pktseq; - const Sendstate cstate = {d->id, d, stat, erc}; + const Sendstate cstate = {d->id, &*d, stat, erc}; sendstates.push_back(cstate); d->sndresult = stat; d->laststatus = d->ps->getStatus(); @@ -1671,7 +1671,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) if (is->stat == blocklen) { // Successful. - successful.push_back(is->it); + successful.push_back(is->mb); rstat = is->stat; was_blocked = false; none_succeeded = false; @@ -1684,7 +1684,7 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc) << "). Setting this socket broken status."); #endif // Turn this link broken - is->it->sndstate = SRT_GST_BROKEN; + is->mb->sndstate = SRT_GST_BROKEN; } } } @@ -3250,7 +3250,7 @@ size_t CUDTGroup::sendBackup_CheckNeedActivate(const vector& idler d->sndresult = stat; d->laststatus = d->ps->getStatus(); - const Sendstate cstate = {d->id, d, stat, erc}; + const Sendstate cstate = {d->id, &*d, stat, erc}; w_sendstates.push_back(cstate); if (stat != -1) @@ -3920,7 +3920,7 @@ int CUDTGroup::sendBackup(const char* buf, int len, SRT_MSGCTRL& w_mc) if (is_unstable && is_zero(u.m_tsUnstableSince)) // Add to unstable only if it wasn't unstable already insert_uniq((unstable), d); - const Sendstate cstate = {d->id, d, stat, erc}; + const Sendstate cstate = {d->id, &*d, stat, erc}; sendstates.push_back(cstate); d->sndresult = stat; d->laststatus = d->ps->getStatus(); @@ -4331,7 +4331,7 @@ void CUDTGroup::ackMessage(int32_t msgno) m_iSndAckedMsgNo = msgno; } -void CUDTGroup::handleKeepalive(gli_t gli) +void CUDTGroup::handleKeepalive(CUDTGroup::SocketData* gli) { // received keepalive for that group member // In backup group it means that the link went IDLE. @@ -4368,7 +4368,7 @@ void CUDTGroup::handleKeepalive(gli_t gli) } } -void CUDTGroup::internalKeepalive(gli_t gli) +void CUDTGroup::internalKeepalive(SocketData* gli) { // This is in response to AGENT SENDING keepalive. This means that there's // no transmission in either direction, but the KEEPALIVE packet from the @@ -4457,18 +4457,18 @@ void CUDTGroup::updateLatestRcv(CUDTSocket* s) UniqueLock lg(m_GroupLock); // Sanity check for a case when getting a deleted socket - if (!s->m_IncludedGroup) + if (!s->m_GroupOf) return; // Under a group lock, we block execution of removal of the socket - // from the group, so if m_IncludedGroup is not NULL, we are granted - // that m_IncludedIter is valid. - gli_t current = s->m_IncludedIter; + // from the group, so if m_GroupOf is not NULL, we are granted + // that m_GroupMemberData is valid. + SocketData* current = s->m_GroupMemberData; for (gli_t gi = m_Group.begin(); gi != m_Group.end(); ++gi) { // Skip the socket that has reported packet reception - if (gi == current) + if (&*gi == current) { HLOGC(grlog.Debug, log << "grp: NOT updating rcv-seq on self @" << gi->id); continue; diff --git a/srtcore/group.h b/srtcore/group.h index 9e226bfd9..684e8ac0e 100644 --- a/srtcore/group.h +++ b/srtcore/group.h @@ -117,7 +117,7 @@ class CUDTGroup struct Sendstate { SRTSOCKET id; - gli_t it; + SocketData* mb; int stat; int code; }; @@ -127,7 +127,7 @@ class CUDTGroup static SocketData prepareData(CUDTSocket* s); - gli_t add(SocketData data); + SocketData* add(SocketData data); struct HaveID { @@ -139,15 +139,17 @@ class CUDTGroup bool operator()(const SocketData& s) { return s.id == id; } }; - gli_t find(SRTSOCKET id) + bool contains(SRTSOCKET id, SocketData*& w_f) { srt::sync::ScopedLock g(m_GroupLock); - gli_t f = std::find_if(m_Group.begin(), m_Group.end(), HaveID(id)); + gli_t f = std::find_if(m_Group.begin(), m_Group.end(), HaveID(id)); if (f == m_Group.end()) { - return gli_NULL(); + w_f = NULL; + return false; } - return f; + w_f = &*f; + return true; } // NEED LOCKING @@ -156,7 +158,7 @@ class CUDTGroup /// Remove the socket from the group container. /// REMEMBER: the group spec should be taken from the socket - /// (set m_IncludedGroup to NULL and m_IncludedIter to grp->gli_NULL()) + /// (set m_GroupOf and m_GroupMemberData to NULL /// PRIOR TO calling this function. /// @param id Socket ID to look for in the container to remove /// @return true if the container still contains any sockets after the operation @@ -219,8 +221,6 @@ class CUDTGroup void setGroupConnected(); - static gli_t gli_NULL() { return GroupContainer::null(); } - int send(const char* buf, int len, SRT_MSGCTRL& w_mc); int sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc); int sendBackup(const char* buf, int len, SRT_MSGCTRL& w_mc); @@ -346,8 +346,8 @@ class CUDTGroup #endif void ackMessage(int32_t msgno); - void handleKeepalive(gli_t); - void internalKeepalive(gli_t); + void handleKeepalive(SocketData*); + void internalKeepalive(SocketData*); private: // Check if there's at least one connected socket. @@ -362,7 +362,6 @@ class CUDTGroup struct GroupContainer { std::list m_List; - static std::list s_NoList; // This is to have a predictable "null iterator". /// This field is used only by some types of groups that need /// to keep track as to which link was lately used. Note that @@ -371,7 +370,7 @@ class CUDTGroup gli_t m_LastActiveLink; GroupContainer() - : m_LastActiveLink(s_NoList.begin()) + : m_LastActiveLink(m_List.end()) { } @@ -380,12 +379,11 @@ class CUDTGroup gli_t begin() { return m_List.begin(); } gli_t end() { return m_List.end(); } - static gli_t null() { return s_NoList.begin(); } bool empty() { return m_List.empty(); } void push_back(const SocketData& data) { m_List.push_back(data); } void clear() { - m_LastActiveLink = null(); + m_LastActiveLink = end(); m_List.clear(); } size_t size() { return m_List.size(); }