Skip to content

Commit b84f3d2

Browse files
authoredDec 2, 2020
[core] CheckValidSockets no longer remove sockets from group, this was causing inconsistency. (Haivision#1687)
1 parent bf6a5b3 commit b84f3d2

File tree

2 files changed

+39
-31
lines changed

2 files changed

+39
-31
lines changed
 

‎srtcore/group.cpp

+37-24
Original file line numberDiff line numberDiff line change
@@ -1062,8 +1062,16 @@ void CUDTGroup::send_CheckValidSockets()
10621062
CUDTSocket* revps = m_pGlobal->locateSocket_LOCKED(d->id);
10631063
if (revps != d->ps)
10641064
{
1065-
HLOGC(gmlog.Debug, log << "group/send_CheckValidSockets: socket @" << d->id << " is no longer valid, REMOVING FROM $" << id());
1066-
remove_LOCKED(d->id);
1065+
// Note: the socket might STILL EXIST, just in the trash, so
1066+
// it can't be found by locateSocket. But it can still be bound
1067+
// to the group. Just mark it broken from upside so that the
1068+
// internal sending procedures will skip it. Removal from the
1069+
// group will happen in GC, which will both remove from
1070+
// group container and cut backward links to the group.
1071+
1072+
HLOGC(gmlog.Debug, log << "group/send_CheckValidSockets: socket @" << d->id << " is no longer valid, setting BROKEN in $" << id());
1073+
d->sndstate = SRT_GST_BROKEN;
1074+
d->rcvstate = SRT_GST_BROKEN;
10671075
}
10681076
}
10691077
}
@@ -1137,7 +1145,6 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc)
11371145
// LOCKED: GroupLock (only)
11381146
// Since this moment GlobControlLock may only be locked if GroupLock is unlocked first.
11391147

1140-
11411148
if (m_bClosing)
11421149
{
11431150
// No temporary locks here. The group lock is scoped.
@@ -1147,18 +1154,21 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc)
11471154
// This simply requires the payload to be sent through every socket in the group
11481155
for (gli_t d = m_Group.begin(); d != m_Group.end(); ++d)
11491156
{
1150-
// Check the socket state prematurely in order not to uselessly
1151-
// send over a socket that is broken.
1152-
CUDT* pu = 0;
1153-
if (d->ps)
1154-
pu = &d->ps->core();
1155-
1156-
if (!pu || pu->m_bBroken)
1157+
if (d->sndstate != SRT_GST_BROKEN)
11571158
{
1158-
HLOGC(gslog.Debug,
1159-
log << "grp/sendBroadcast: socket @" << d->id << " detected +Broken - transit to BROKEN");
1160-
d->sndstate = SRT_GST_BROKEN;
1161-
d->rcvstate = SRT_GST_BROKEN;
1159+
// Check the socket state prematurely in order not to uselessly
1160+
// send over a socket that is broken.
1161+
CUDT* const pu = (d->ps)
1162+
? &d->ps->core()
1163+
: NULL;
1164+
1165+
if (!pu || pu->m_bBroken)
1166+
{
1167+
HLOGC(gslog.Debug,
1168+
log << "grp/sendBroadcast: socket @" << d->id << " detected +Broken - transit to BROKEN");
1169+
d->sndstate = SRT_GST_BROKEN;
1170+
d->rcvstate = SRT_GST_BROKEN;
1171+
}
11621172
}
11631173

11641174
// Check socket sndstate before sending
@@ -3776,17 +3786,20 @@ int CUDTGroup::sendBackup(const char* buf, int len, SRT_MSGCTRL& w_mc)
37763786
// First, check status of every link - no matter if idle or active.
37773787
for (gli_t d = m_Group.begin(); d != m_Group.end(); ++d)
37783788
{
3779-
// Check the socket state prematurely in order not to uselessly
3780-
// send over a socket that is broken.
3781-
CUDT* pu = 0;
3782-
if (d->ps)
3783-
pu = &d->ps->core();
3784-
3785-
if (!pu || pu->m_bBroken)
3789+
if (d->sndstate != SRT_GST_BROKEN)
37863790
{
3787-
HLOGC(gslog.Debug, log << "grp/sendBackup: socket @" << d->id << " detected +Broken - transit to BROKEN");
3788-
d->sndstate = SRT_GST_BROKEN;
3789-
d->rcvstate = SRT_GST_BROKEN;
3791+
// Check the socket state prematurely in order not to uselessly
3792+
// send over a socket that is broken.
3793+
CUDT* const pu = (d->ps)
3794+
? &d->ps->core()
3795+
: NULL;
3796+
3797+
if (!pu || pu->m_bBroken)
3798+
{
3799+
HLOGC(gslog.Debug, log << "grp/sendBackup: socket @" << d->id << " detected +Broken - transit to BROKEN");
3800+
d->sndstate = SRT_GST_BROKEN;
3801+
d->rcvstate = SRT_GST_BROKEN;
3802+
}
37903803
}
37913804

37923805
// Check socket sndstate before sending

‎srtcore/group.h

+2-7
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,9 @@ class CUDTGroup
162162
/// @return true if the container still contains any sockets after the operation
163163
bool remove(SRTSOCKET id)
164164
{
165+
using srt_logging::gmlog;
165166
srt::sync::ScopedLock g(m_GroupLock);
166-
return remove_LOCKED(id);
167-
}
168167

169-
// No-locking version of the function above.
170-
bool remove_LOCKED(SRTSOCKET id)
171-
{
172-
using srt_logging::gmlog;
173168
bool empty = false;
174169
HLOGC(gmlog.Debug, log << "group/remove: going to remove @" << id << " from $" << m_GroupID);
175170

@@ -200,7 +195,7 @@ class CUDTGroup
200195
}
201196
else
202197
{
203-
HLOGC(gmlog.Debug, log << "group/remove: IPE: id @" << id << " NOT FOUND (might be ok, if removed already by CheckValidSockets)");
198+
HLOGC(gmlog.Debug, log << "group/remove: IPE: id @" << id << " NOT FOUND");
204199
empty = true; // not exactly true, but this is to cause error on group in the APP
205200
}
206201

0 commit comments

Comments
 (0)
Please sign in to comment.