Skip to content

Commit f8319d6

Browse files
winlinvipsuzp1984
andauthored
Fix crash when quiting. v6.0.151 v7.0.10 (#4157)
1. Remove the srs_global_dispose, which causes the crash when still publishing when quit. 2. Always call _srs_thread_pool->initialize for single thread. 3. Support `--signal-api` to send signal by HTTP API, because CLion eliminate the signals. --- Co-authored-by: Jacob Su <[email protected]>
1 parent cc6db25 commit f8319d6

11 files changed

+89
-161
lines changed

trunk/auto/auto_headers.sh

+5
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ if [[ $SRS_SINGLE_THREAD == YES ]]; then
201201
else
202202
srs_undefine_macro "SRS_SINGLE_THREAD" $SRS_AUTO_HEADERS_H
203203
fi
204+
if [[ $SRS_SIGNAL_API == YES ]]; then
205+
srs_define_macro "SRS_SIGNAL_API" $SRS_AUTO_HEADERS_H
206+
else
207+
srs_undefine_macro "SRS_SIGNAL_API" $SRS_AUTO_HEADERS_H
208+
fi
204209
if [[ $SRS_LOG_LEVEL_V2 == YES ]]; then
205210
srs_define_macro "SRS_LOG_LEVEL_V2" $SRS_AUTO_HEADERS_H
206211
else

trunk/auto/options.sh

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ SRS_CLEAN=YES # Whether do "make clean" when configure.
8585
SRS_SIMULATOR=NO # Whether enable RTC simulate API.
8686
SRS_GENERATE_OBJS=NO # Whether generate objs and quit.
8787
SRS_SINGLE_THREAD=YES # Whether force single thread mode.
88+
SRS_SIGNAL_API=NO # Use http API to simulate sending signal to SRS, for debugging.
8889
#
8990
################################################################
9091
# Performance options.
@@ -235,6 +236,7 @@ Experts:
235236
--simulator=on|off RTC: Whether enable network simulator. Default: $(value2switch $SRS_SIMULATOR)
236237
--generate-objs=on|off RTC: Whether generate objs and quit. Default: $(value2switch $SRS_GENERATE_OBJS)
237238
--single-thread=on|off Whether force single thread mode. Default: $(value2switch $SRS_SINGLE_THREAD)
239+
--signal-api=on|off Whether support sending signal by HTTP API. Default: $(value2switch $SRS_SIGNAL_API)
238240
--build-tag=<TAG> Set the build object directory suffix.
239241
--debug=on|off Whether enable the debug code, may hurt performance. Default: $(value2switch $SRS_DEBUG)
240242
--debug-stats=on|off Whether enable the debug stats, may hurt performance. Default: $(value2switch $SRS_DEBUG_STATS)
@@ -339,6 +341,7 @@ function parse_user_option() {
339341
--simulator) SRS_SIMULATOR=$(switch2value $value) ;;
340342
--generate-objs) SRS_GENERATE_OBJS=$(switch2value $value) ;;
341343
--single-thread) SRS_SINGLE_THREAD=$(switch2value $value) ;;
344+
--signal-api) SRS_SIGNAL_API=$(switch2value $value) ;;
342345
--ffmpeg-fit) SRS_FFMPEG_FIT=$(switch2value $value) ;;
343346
--ffmpeg-opus) SRS_FFMPEG_OPUS=$(switch2value $value) ;;
344347
--h265) SRS_H265=$(switch2value $value) ;;
@@ -681,6 +684,7 @@ function regenerate_options() {
681684
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sanitizer-log=$(value2switch $SRS_SANITIZER_LOG)"
682685
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cygwin64=$(value2switch $SRS_CYGWIN64)"
683686
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --single-thread=$(value2switch $SRS_SINGLE_THREAD)"
687+
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --signal-api=$(value2switch $SRS_SIGNAL_API)"
684688
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --generic-linux=$(value2switch $SRS_GENERIC_LINUX)"
685689
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --build-cache=$(value2switch $SRS_BUILD_CACHE)"
686690
if [[ $SRS_CROSS_BUILD_ARCH != "" ]]; then SRS_AUTO_CONFIGURE="$SRS_AUTO_CONFIGURE --arch=$SRS_CROSS_BUILD_ARCH"; fi

trunk/doc/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The changelog for SRS.
77
<a name="v7-changes"></a>
88

99
## SRS 7.0 Changelog
10+
* v7.0, 2024-08-24, Merge [#4157](https://github.com/ossrs/srs/pull/4157): Fix crash when quiting. v7.0.10 (#4157)
1011
* v7.0, 2024-08-24, Merge [#4156](https://github.com/ossrs/srs/pull/4156): Build: Fix srs_mp4_parser compiling error. v7.0.9 (#4156)
1112
* v7.0, 2024-08-22, Merge [#4154](https://github.com/ossrs/srs/pull/4154): ASAN: Disable memory leak detection by default. v7.0.8 (#4154)
1213
* v7.0, 2024-08-21, Merge [#4149](https://github.com/ossrs/srs/pull/4149): ST: Replace macros with explicit code for better understanding. v7.0.7 (#4149)
@@ -21,6 +22,7 @@ The changelog for SRS.
2122
<a name="v6-changes"></a>
2223

2324
## SRS 6.0 Changelog
25+
* v6.0, 2024-08-24, Merge [#4157](https://github.com/ossrs/srs/pull/4157): Fix crash when quiting. v6.0.151 (#4157)
2426
* v6.0, 2024-08-24, Merge [#4156](https://github.com/ossrs/srs/pull/4156): Build: Fix srs_mp4_parser compiling error. v6.0.150 (#4156)
2527
* v6.0, 2024-08-21, Merge [#4150](https://github.com/ossrs/srs/pull/4150): API: Support new HTTP API for VALGRIND. v6.0.149 (#4150)
2628
* v6.0, 2024-08-15, Merge [#4144](https://github.com/ossrs/srs/pull/4144): HTTP-FLV: Crash when multiple viewers. v6.0.148 (#4144)

trunk/src/app/srs_app_http_api.cpp

+53-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,12 @@ srs_error_t SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r
272272
urls->set("clusters", SrsJsonAny::str("origin cluster server API"));
273273
urls->set("perf", SrsJsonAny::str("System performance stat"));
274274
urls->set("tcmalloc", SrsJsonAny::str("tcmalloc api with params ?page=summary|api"));
275+
#ifdef SRS_VALGRIND
275276
urls->set("valgrind", SrsJsonAny::str("valgrind api with params ?check=full|added|changed|new|quick"));
277+
#endif
278+
#ifdef SRS_SIGNAL_API
279+
urls->set("signal", SrsJsonAny::str("simulate signal api with params ?signo=SIGHUP|SIGUSR1|SIGUSR2|SIGTERM|SIGQUIT|SIGABRT|SIGINT"));
280+
#endif
276281

277282
SrsJsonObject* tests = SrsJsonAny::object();
278283
obj->set("tests", tests);
@@ -1097,7 +1102,6 @@ srs_error_t SrsGoApiTcmalloc::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
10971102
#endif
10981103

10991104
#ifdef SRS_VALGRIND
1100-
11011105
SrsGoApiValgrind::SrsGoApiValgrind()
11021106
{
11031107
trd_ = NULL;
@@ -1191,6 +1195,54 @@ srs_error_t SrsGoApiValgrind::cycle()
11911195
}
11921196
#endif
11931197

1198+
#ifdef SRS_SIGNAL_API
1199+
SrsGoApiSignal::SrsGoApiSignal()
1200+
{
1201+
}
1202+
1203+
SrsGoApiSignal::~SrsGoApiSignal()
1204+
{
1205+
}
1206+
1207+
srs_error_t SrsGoApiSignal::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
1208+
{
1209+
srs_error_t err = srs_success;
1210+
1211+
std::string signal = r->query_get("signo");
1212+
srs_trace("query signo=%s", signal.c_str());
1213+
1214+
int signo = SIGINT;
1215+
if (signal == "SIGHUP") {
1216+
signo = SRS_SIGNAL_RELOAD;
1217+
} else if (signal == "SIGUSR1") {
1218+
signo = SRS_SIGNAL_REOPEN_LOG;
1219+
} else if (signal == "SIGUSR2") {
1220+
signo = SRS_SIGNAL_UPGRADE;
1221+
} else if (signal == "SIGTERM") {
1222+
signo = SRS_SIGNAL_FAST_QUIT;
1223+
} else if (signal == "SIGQUIT") {
1224+
signo = SRS_SIGNAL_GRACEFULLY_QUIT;
1225+
} else if (signal == "SIGABRT") {
1226+
signo = SRS_SIGNAL_ASSERT_ABORT;
1227+
}
1228+
1229+
_srs_hybrid->srs()->instance()->on_signal(signo);
1230+
1231+
// By default, response the json style response.
1232+
SrsUniquePtr<SrsJsonObject> obj(SrsJsonAny::object());
1233+
1234+
obj->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
1235+
1236+
SrsJsonObject* res = SrsJsonAny::object();
1237+
res->set("signal", SrsJsonAny::str(signal.c_str()));
1238+
res->set("help", SrsJsonAny::str("?signo=SIGHUP|SIGUSR1|SIGUSR2|SIGTERM|SIGQUIT|SIGABRT|SIGINT"));
1239+
res->set("signo", SrsJsonAny::integer(signo));
1240+
obj->set("data", res);
1241+
1242+
return srs_api_response(w, r, obj->dumps());
1243+
}
1244+
#endif
1245+
11941246
SrsGoApiMetrics::SrsGoApiMetrics()
11951247
{
11961248
enabled_ = _srs_config->get_exporter_enabled();

trunk/src/app/srs_app_http_api.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,17 @@ class SrsGoApiValgrind : public ISrsHttpHandler, public ISrsCoroutineHandler
233233
};
234234
#endif
235235

236+
#ifdef SRS_SIGNAL_API
237+
class SrsGoApiSignal : public ISrsHttpHandler
238+
{
239+
public:
240+
SrsGoApiSignal();
241+
virtual ~SrsGoApiSignal();
242+
public:
243+
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
244+
};
245+
#endif
246+
236247
class SrsGoApiMetrics : public ISrsHttpHandler
237248
{
238249
private:

trunk/src/app/srs_app_server.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,13 @@ srs_error_t SrsServer::http_handle()
784784
}
785785
#endif
786786

787+
#ifdef SRS_SIGNAL_API
788+
// Simulate the signal by HTTP API, for debug signal issues in CLion.
789+
if ((err = http_api_mux->handle("/api/v1/signal", new SrsGoApiSignal())) != srs_success) {
790+
return srs_error_wrap(err, "handle signal errors");
791+
}
792+
#endif
793+
787794
// metrics by prometheus
788795
if ((err = http_api_mux->handle("/metrics", new SrsGoApiMetrics())) != srs_success) {
789796
return srs_error_wrap(err, "handle tests errors");

trunk/src/app/srs_app_threads.cpp

-148
Original file line numberDiff line numberDiff line change
@@ -455,154 +455,6 @@ srs_error_t srs_global_initialize()
455455
return err;
456456
}
457457

458-
void srs_global_dispose()
459-
{
460-
// Note that hybrid depends on sources.
461-
srs_freep(_srs_hybrid);
462-
srs_freep(_srs_sources);
463-
464-
srs_freep(_srs_clock);
465-
466-
srs_freep(_srs_stages);
467-
srs_freep(_srs_circuit_breaker);
468-
469-
#ifdef SRS_SRT
470-
srs_freep(_srs_srt_sources);
471-
#endif
472-
473-
#ifdef SRS_RTC
474-
srs_freep(_srs_rtc_sources);
475-
srs_freep(_srs_blackhole);
476-
srs_freep(_srs_rtc_manager);
477-
srs_freep(_srs_rtc_dtls_certificate);
478-
#endif
479-
#ifdef SRS_GB28181
480-
srs_freep(_srs_gb_manager);
481-
#endif
482-
483-
srs_freep(_srs_pps_ids);
484-
srs_freep(_srs_pps_fids);
485-
srs_freep(_srs_pps_fids_level0);
486-
srs_freep(_srs_pps_dispose);
487-
488-
srs_freep(_srs_pps_timer);
489-
srs_freep(_srs_pps_conn);
490-
srs_freep(_srs_pps_pub);
491-
492-
#ifdef SRS_RTC
493-
srs_freep(_srs_pps_snack);
494-
srs_freep(_srs_pps_snack2);
495-
srs_freep(_srs_pps_snack3);
496-
srs_freep(_srs_pps_snack4);
497-
srs_freep(_srs_pps_sanack);
498-
srs_freep(_srs_pps_svnack);
499-
500-
srs_freep(_srs_pps_rnack);
501-
srs_freep(_srs_pps_rnack2);
502-
srs_freep(_srs_pps_rhnack);
503-
srs_freep(_srs_pps_rmnack);
504-
#endif
505-
506-
#if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS)
507-
srs_freep(_srs_pps_recvfrom);
508-
srs_freep(_srs_pps_recvfrom_eagain);
509-
srs_freep(_srs_pps_sendto);
510-
srs_freep(_srs_pps_sendto_eagain);
511-
512-
srs_freep(_srs_pps_read);
513-
srs_freep(_srs_pps_read_eagain);
514-
srs_freep(_srs_pps_readv);
515-
srs_freep(_srs_pps_readv_eagain);
516-
srs_freep(_srs_pps_writev);
517-
srs_freep(_srs_pps_writev_eagain);
518-
519-
srs_freep(_srs_pps_recvmsg);
520-
srs_freep(_srs_pps_recvmsg_eagain);
521-
srs_freep(_srs_pps_sendmsg);
522-
srs_freep(_srs_pps_sendmsg_eagain);
523-
524-
srs_freep(_srs_pps_epoll);
525-
srs_freep(_srs_pps_epoll_zero);
526-
srs_freep(_srs_pps_epoll_shake);
527-
srs_freep(_srs_pps_epoll_spin);
528-
529-
srs_freep(_srs_pps_sched_15ms);
530-
srs_freep(_srs_pps_sched_20ms);
531-
srs_freep(_srs_pps_sched_25ms);
532-
srs_freep(_srs_pps_sched_30ms);
533-
srs_freep(_srs_pps_sched_35ms);
534-
srs_freep(_srs_pps_sched_40ms);
535-
srs_freep(_srs_pps_sched_80ms);
536-
srs_freep(_srs_pps_sched_160ms);
537-
srs_freep(_srs_pps_sched_s);
538-
#endif
539-
540-
srs_freep(_srs_pps_clock_15ms);
541-
srs_freep(_srs_pps_clock_20ms);
542-
srs_freep(_srs_pps_clock_25ms);
543-
srs_freep(_srs_pps_clock_30ms);
544-
srs_freep(_srs_pps_clock_35ms);
545-
srs_freep(_srs_pps_clock_40ms);
546-
srs_freep(_srs_pps_clock_80ms);
547-
srs_freep(_srs_pps_clock_160ms);
548-
srs_freep(_srs_pps_timer_s);
549-
550-
#if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS)
551-
srs_freep(_srs_pps_thread_run);
552-
srs_freep(_srs_pps_thread_idle);
553-
srs_freep(_srs_pps_thread_yield);
554-
srs_freep(_srs_pps_thread_yield2);
555-
#endif
556-
557-
srs_freep(_srs_pps_rpkts);
558-
srs_freep(_srs_pps_addrs);
559-
srs_freep(_srs_pps_fast_addrs);
560-
561-
srs_freep(_srs_pps_spkts);
562-
srs_freep(_srs_pps_objs_msgs);
563-
564-
#ifdef SRS_RTC
565-
srs_freep(_srs_pps_sstuns);
566-
srs_freep(_srs_pps_srtcps);
567-
srs_freep(_srs_pps_srtps);
568-
569-
srs_freep(_srs_pps_rstuns);
570-
srs_freep(_srs_pps_rrtps);
571-
srs_freep(_srs_pps_rrtcps);
572-
573-
srs_freep(_srs_pps_aloss2);
574-
575-
srs_freep(_srs_pps_pli);
576-
srs_freep(_srs_pps_twcc);
577-
srs_freep(_srs_pps_rr);
578-
579-
srs_freep(_srs_pps_objs_rtps);
580-
srs_freep(_srs_pps_objs_rraw);
581-
srs_freep(_srs_pps_objs_rfua);
582-
srs_freep(_srs_pps_objs_rbuf);
583-
srs_freep(_srs_pps_objs_rothers);
584-
#endif
585-
586-
srs_freep(_srs_dvr_async);
587-
588-
#ifdef SRS_APM
589-
srs_freep(_srs_cls);
590-
srs_freep(_srs_apm);
591-
#endif
592-
593-
srs_freep(_srs_reload_err);
594-
595-
// Note that we never free the logging, because it's used after thread terminated.
596-
//srs_freep(_srs_log);
597-
//srs_freep(_srs_config);
598-
//srs_freep(_srs_context);
599-
//srs_freep(_srs_pps_cids_get);
600-
//srs_freep(_srs_pps_cids_set);
601-
602-
// Dispose ST finally, which may be used by other global objects.
603-
srs_st_destroy();
604-
}
605-
606458
SrsThreadMutex::SrsThreadMutex()
607459
{
608460
// https://man7.org/linux/man-pages/man3/pthread_mutexattr_init.3.html

trunk/src/app/srs_app_threads.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ extern SrsCircuitBreaker* _srs_circuit_breaker;
5353

5454
// Initialize global shared variables cross all threads.
5555
extern srs_error_t srs_global_initialize();
56-
extern void srs_global_dispose();
5756

5857
// The thread mutex wrapper, without error.
5958
class SrsThreadMutex

trunk/src/core/srs_core_version6.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 6
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 150
12+
#define VERSION_REVISION 151
1313

1414
#endif

trunk/src/core/srs_core_version7.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 7
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 9
12+
#define VERSION_REVISION 10
1313

1414
#endif

trunk/src/main/srs_main_server.cpp

+5-9
Original file line numberDiff line numberDiff line change
@@ -463,17 +463,17 @@ srs_error_t run_directly_or_daemon()
463463
srs_error_t run_hybrid_server(void* arg);
464464
srs_error_t run_in_thread_pool()
465465
{
466-
#ifdef SRS_SINGLE_THREAD
467-
srs_trace("Run in single thread mode");
468-
return run_hybrid_server(NULL);
469-
#else
470466
srs_error_t err = srs_success;
471467

472-
// Initialize the thread pool.
468+
// Initialize the thread pool, even if we run in single thread mode.
473469
if ((err = _srs_thread_pool->initialize()) != srs_success) {
474470
return srs_error_wrap(err, "init thread pool");
475471
}
476472

473+
#ifdef SRS_SINGLE_THREAD
474+
srs_trace("Run in single thread mode");
475+
return run_hybrid_server(NULL);
476+
#else
477477
// Start the hybrid service worker thread, for RTMP and RTC server, etc.
478478
if ((err = _srs_thread_pool->execute("hybrid", run_hybrid_server, (void*)NULL)) != srs_success) {
479479
return srs_error_wrap(err, "start hybrid server thread");
@@ -525,10 +525,6 @@ srs_error_t run_hybrid_server(void* /*arg*/)
525525
// After all done, stop and cleanup.
526526
_srs_hybrid->stop();
527527

528-
// Dispose all global objects, note that we should do this in the hybrid thread, because it may
529-
// depend on the ST when disposing.
530-
srs_global_dispose();
531-
532528
return err;
533529
}
534530

0 commit comments

Comments
 (0)