@@ -945,18 +945,29 @@ srs_error_t SrsRtcPlayStream::do_request_keyframe(uint32_t ssrc, SrsContextId ci
945
945
946
946
SrsRtcPublishRtcpTimer::SrsRtcPublishRtcpTimer (SrsRtcPublishStream* p) : p_(p)
947
947
{
948
+ lock_ = srs_mutex_new ();
948
949
_srs_hybrid->timer1s ()->subscribe (this );
949
950
}
950
951
951
952
SrsRtcPublishRtcpTimer::~SrsRtcPublishRtcpTimer ()
952
953
{
953
- _srs_hybrid->timer1s ()->unsubscribe (this );
954
+ if (true ) {
955
+ SrsLocker (lock_);
956
+ _srs_hybrid->timer1s ()->unsubscribe (this );
957
+ }
958
+ srs_mutex_destroy (lock_);
954
959
}
955
960
956
961
srs_error_t SrsRtcPublishRtcpTimer::on_timer (srs_utime_t interval)
957
962
{
958
963
srs_error_t err = srs_success;
959
964
965
+ // This is a very heavy function, and it may potentially cause a coroutine switch.
966
+ // Therefore, during this function, the 'this' pointer might become invalid because
967
+ // the object could be freed by another thread. As a result, we must lock the object
968
+ // to prevent it from being freed.
969
+ SrsLocker (lock_);
970
+
960
971
++_srs_pps_pub->sugar ;
961
972
962
973
if (!p_->is_started ) {
@@ -981,18 +992,29 @@ srs_error_t SrsRtcPublishRtcpTimer::on_timer(srs_utime_t interval)
981
992
982
993
SrsRtcPublishTwccTimer::SrsRtcPublishTwccTimer (SrsRtcPublishStream* p) : p_(p)
983
994
{
995
+ lock_ = srs_mutex_new ();
984
996
_srs_hybrid->timer100ms ()->subscribe (this );
985
997
}
986
998
987
999
SrsRtcPublishTwccTimer::~SrsRtcPublishTwccTimer ()
988
1000
{
989
- _srs_hybrid->timer100ms ()->unsubscribe (this );
1001
+ if (true ) {
1002
+ SrsLocker (lock_);
1003
+ _srs_hybrid->timer100ms ()->unsubscribe (this );
1004
+ }
1005
+ srs_mutex_destroy (lock_);
990
1006
}
991
1007
992
1008
srs_error_t SrsRtcPublishTwccTimer::on_timer (srs_utime_t interval)
993
1009
{
994
1010
srs_error_t err = srs_success;
995
1011
1012
+ // This is a very heavy function, and it may potentially cause a coroutine switch.
1013
+ // Therefore, during this function, the 'this' pointer might become invalid because
1014
+ // the object could be freed by another thread. As a result, we must lock the object
1015
+ // to prevent it from being freed.
1016
+ SrsLocker (lock_);
1017
+
996
1018
++_srs_pps_pub->sugar ;
997
1019
998
1020
if (!p_->is_started ) {
@@ -1739,12 +1761,17 @@ void SrsRtcPublishStream::update_send_report_time(uint32_t ssrc, const SrsNtp& n
1739
1761
1740
1762
SrsRtcConnectionNackTimer::SrsRtcConnectionNackTimer (SrsRtcConnection* p) : p_(p)
1741
1763
{
1764
+ lock_ = srs_mutex_new ();
1742
1765
_srs_hybrid->timer20ms ()->subscribe (this );
1743
1766
}
1744
1767
1745
1768
SrsRtcConnectionNackTimer::~SrsRtcConnectionNackTimer ()
1746
1769
{
1747
- _srs_hybrid->timer20ms ()->unsubscribe (this );
1770
+ if (true ) {
1771
+ SrsLocker (lock_);
1772
+ _srs_hybrid->timer20ms ()->unsubscribe (this );
1773
+ }
1774
+ srs_mutex_destroy (lock_);
1748
1775
}
1749
1776
1750
1777
srs_error_t SrsRtcConnectionNackTimer::on_timer (srs_utime_t interval)
@@ -1755,6 +1782,12 @@ srs_error_t SrsRtcConnectionNackTimer::on_timer(srs_utime_t interval)
1755
1782
return err;
1756
1783
}
1757
1784
1785
+ // This is a very heavy function, and it may potentially cause a coroutine switch.
1786
+ // Therefore, during this function, the 'this' pointer might become invalid because
1787
+ // the object could be freed by another thread. As a result, we must lock the object
1788
+ // to prevent it from being freed.
1789
+ SrsLocker (lock_);
1790
+
1758
1791
++_srs_pps_conn->sugar ;
1759
1792
1760
1793
// If circuit-breaker is enabled, disable nack.
0 commit comments