@@ -1062,8 +1062,16 @@ void CUDTGroup::send_CheckValidSockets()
1062
1062
CUDTSocket* revps = m_pGlobal->locateSocket_LOCKED (d->id );
1063
1063
if (revps != d->ps )
1064
1064
{
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;
1067
1075
}
1068
1076
}
1069
1077
}
@@ -1137,7 +1145,6 @@ int CUDTGroup::sendBroadcast(const char* buf, int len, SRT_MSGCTRL& w_mc)
1137
1145
// LOCKED: GroupLock (only)
1138
1146
// Since this moment GlobControlLock may only be locked if GroupLock is unlocked first.
1139
1147
1140
-
1141
1148
if (m_bClosing)
1142
1149
{
1143
1150
// 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)
1147
1154
// This simply requires the payload to be sent through every socket in the group
1148
1155
for (gli_t d = m_Group.begin (); d != m_Group.end (); ++d)
1149
1156
{
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)
1157
1158
{
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
+ }
1162
1172
}
1163
1173
1164
1174
// Check socket sndstate before sending
@@ -3776,17 +3786,20 @@ int CUDTGroup::sendBackup(const char* buf, int len, SRT_MSGCTRL& w_mc)
3776
3786
// First, check status of every link - no matter if idle or active.
3777
3787
for (gli_t d = m_Group.begin (); d != m_Group.end (); ++d)
3778
3788
{
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)
3786
3790
{
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
+ }
3790
3803
}
3791
3804
3792
3805
// Check socket sndstate before sending
0 commit comments