Skip to content

Commit

Permalink
Fix crash when quiting.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Aug 24, 2024
1 parent 47f8fe4 commit e0402d6
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 159 deletions.
5 changes: 5 additions & 0 deletions trunk/auto/auto_headers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ if [[ $SRS_SINGLE_THREAD == YES ]]; then
else
srs_undefine_macro "SRS_SINGLE_THREAD" $SRS_AUTO_HEADERS_H
fi
if [[ $SRS_SIGNAL_API == YES ]]; then
srs_define_macro "SRS_SIGNAL_API" $SRS_AUTO_HEADERS_H
else
srs_undefine_macro "SRS_SIGNAL_API" $SRS_AUTO_HEADERS_H
fi
if [[ $SRS_LOG_LEVEL_V2 == YES ]]; then
srs_define_macro "SRS_LOG_LEVEL_V2" $SRS_AUTO_HEADERS_H
else
Expand Down
4 changes: 4 additions & 0 deletions trunk/auto/options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ SRS_CLEAN=YES # Whether do "make clean" when configure.
SRS_SIMULATOR=NO # Whether enable RTC simulate API.
SRS_GENERATE_OBJS=NO # Whether generate objs and quit.
SRS_SINGLE_THREAD=YES # Whether force single thread mode.
SRS_SIGNAL_API=NO # Use http API to simulate sending signal to SRS, for debugging.
#
################################################################
# Performance options.
Expand Down Expand Up @@ -235,6 +236,7 @@ Experts:
--simulator=on|off RTC: Whether enable network simulator. Default: $(value2switch $SRS_SIMULATOR)
--generate-objs=on|off RTC: Whether generate objs and quit. Default: $(value2switch $SRS_GENERATE_OBJS)
--single-thread=on|off Whether force single thread mode. Default: $(value2switch $SRS_SINGLE_THREAD)
--signal-api=on|off Whether support sending signal by HTTP API. Default: $(value2switch $SRS_SIGNAL_API)
--build-tag=<TAG> Set the build object directory suffix.
--debug=on|off Whether enable the debug code, may hurt performance. Default: $(value2switch $SRS_DEBUG)
--debug-stats=on|off Whether enable the debug stats, may hurt performance. Default: $(value2switch $SRS_DEBUG_STATS)
Expand Down Expand Up @@ -339,6 +341,7 @@ function parse_user_option() {
--simulator) SRS_SIMULATOR=$(switch2value $value) ;;
--generate-objs) SRS_GENERATE_OBJS=$(switch2value $value) ;;
--single-thread) SRS_SINGLE_THREAD=$(switch2value $value) ;;
--signal-api) SRS_SIGNAL_API=$(switch2value $value) ;;
--ffmpeg-fit) SRS_FFMPEG_FIT=$(switch2value $value) ;;
--ffmpeg-opus) SRS_FFMPEG_OPUS=$(switch2value $value) ;;
--h265) SRS_H265=$(switch2value $value) ;;
Expand Down Expand Up @@ -681,6 +684,7 @@ function regenerate_options() {
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sanitizer-log=$(value2switch $SRS_SANITIZER_LOG)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cygwin64=$(value2switch $SRS_CYGWIN64)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --single-thread=$(value2switch $SRS_SINGLE_THREAD)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --signal-api=$(value2switch $SRS_SIGNAL_API)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --generic-linux=$(value2switch $SRS_GENERIC_LINUX)"
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --build-cache=$(value2switch $SRS_BUILD_CACHE)"
if [[ $SRS_CROSS_BUILD_ARCH != "" ]]; then SRS_AUTO_CONFIGURE="$SRS_AUTO_CONFIGURE --arch=$SRS_CROSS_BUILD_ARCH"; fi
Expand Down
54 changes: 53 additions & 1 deletion trunk/src/app/srs_app_http_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,12 @@ srs_error_t SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r
urls->set("clusters", SrsJsonAny::str("origin cluster server API"));
urls->set("perf", SrsJsonAny::str("System performance stat"));
urls->set("tcmalloc", SrsJsonAny::str("tcmalloc api with params ?page=summary|api"));
#ifdef SRS_VALGRIND
urls->set("valgrind", SrsJsonAny::str("valgrind api with params ?check=full|added|changed|new|quick"));
#endif
#ifdef SRS_SIGNAL_API
urls->set("signal", SrsJsonAny::str("simulate signal api with params ?signo=SIGHUP|SIGUSR1|SIGUSR2|SIGTERM|SIGQUIT|SIGABRT|SIGINT"));
#endif

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

#ifdef SRS_VALGRIND

SrsGoApiValgrind::SrsGoApiValgrind()
{
trd_ = NULL;
Expand Down Expand Up @@ -1191,6 +1195,54 @@ srs_error_t SrsGoApiValgrind::cycle()
}
#endif

#ifdef SRS_SIGNAL_API
SrsGoApiSignal::SrsGoApiSignal()
{
}

SrsGoApiSignal::~SrsGoApiSignal()
{
}

srs_error_t SrsGoApiSignal::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
srs_error_t err = srs_success;

std::string signal = r->query_get("signo");
srs_trace("query signo=%s", signal.c_str());

int signo = SIGINT;
if (signal == "SIGHUP") {
signo = SRS_SIGNAL_RELOAD;
} else if (signal == "SIGUSR1") {
signo = SRS_SIGNAL_REOPEN_LOG;
} else if (signal == "SIGUSR2") {
signo = SRS_SIGNAL_UPGRADE;
} else if (signal == "SIGTERM") {
signo = SRS_SIGNAL_FAST_QUIT;
} else if (signal == "SIGQUIT") {
signo = SRS_SIGNAL_GRACEFULLY_QUIT;
} else if (signal == "SIGABRT") {
signo = SRS_SIGNAL_ASSERT_ABORT;
}

_srs_hybrid->srs()->instance()->on_signal(signo);

// By default, response the json style response.
SrsUniquePtr<SrsJsonObject> obj(SrsJsonAny::object());

obj->set("code", SrsJsonAny::integer(ERROR_SUCCESS));

SrsJsonObject* res = SrsJsonAny::object();
res->set("signal", SrsJsonAny::str(signal.c_str()));
res->set("help", SrsJsonAny::str("?signo=SIGHUP|SIGUSR1|SIGUSR2|SIGTERM|SIGQUIT|SIGABRT|SIGINT"));
res->set("signo", SrsJsonAny::integer(signo));
obj->set("data", res);

return srs_api_response(w, r, obj->dumps());
}
#endif

SrsGoApiMetrics::SrsGoApiMetrics()
{
enabled_ = _srs_config->get_exporter_enabled();
Expand Down
11 changes: 11 additions & 0 deletions trunk/src/app/srs_app_http_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,17 @@ class SrsGoApiValgrind : public ISrsHttpHandler, public ISrsCoroutineHandler
};
#endif

#ifdef SRS_SIGNAL_API
class SrsGoApiSignal : public ISrsHttpHandler
{
public:
SrsGoApiSignal();
virtual ~SrsGoApiSignal();
public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
};
#endif

class SrsGoApiMetrics : public ISrsHttpHandler
{
private:
Expand Down
7 changes: 7 additions & 0 deletions trunk/src/app/srs_app_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,13 @@ srs_error_t SrsServer::http_handle()
}
#endif

#ifdef SRS_SIGNAL_API
// Simulate the signal by HTTP API, for debug signal issues in CLion.
if ((err = http_api_mux->handle("/api/v1/signal", new SrsGoApiSignal())) != srs_success) {
return srs_error_wrap(err, "handle signal errors");
}
#endif

// metrics by prometheus
if ((err = http_api_mux->handle("/metrics", new SrsGoApiMetrics())) != srs_success) {
return srs_error_wrap(err, "handle tests errors");
Expand Down
14 changes: 14 additions & 0 deletions trunk/src/app/srs_app_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1889,6 +1889,7 @@ SrsLiveSource::SrsLiveSource()
can_publish_ = true;
stream_die_at_ = 0;
publisher_idle_at_ = 0;
disposed_ = false;

handler = NULL;
bridge_ = NULL;
Expand All @@ -1910,6 +1911,9 @@ SrsLiveSource::SrsLiveSource()
SrsLiveSource::~SrsLiveSource()
{
_srs_config->unsubscribe(this);

// Also disposed when free it.
disposed_ = true;

// never free the consumers,
// for all consumers are auto free.
Expand All @@ -1934,6 +1938,11 @@ SrsLiveSource::~SrsLiveSource()

void SrsLiveSource::dispose()
{
if (disposed_) {
return;
}
disposed_ = true;

hub->dispose();
meta->dispose();
gop_cache->dispose();
Expand Down Expand Up @@ -2613,6 +2622,11 @@ srs_error_t SrsLiveSource::on_publish()

void SrsLiveSource::on_unpublish()
{
// If source is disposed, the system status is stopping, ignore the unpublish event.
if (disposed_) {
return;
}

// ignore when already unpublished.
if (can_publish_) {
return;
Expand Down
2 changes: 2 additions & 0 deletions trunk/src/app/srs_app_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,8 @@ class SrsLiveSource : public ISrsReloadHandler
srs_utime_t stream_die_at_;
// The last idle time, while idle means no players.
srs_utime_t publisher_idle_at_;
// Whether source has been disposed.
bool disposed_;
public:
SrsLiveSource();
virtual ~SrsLiveSource();
Expand Down
148 changes: 0 additions & 148 deletions trunk/src/app/srs_app_threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,154 +455,6 @@ srs_error_t srs_global_initialize()
return err;
}

void srs_global_dispose()
{
// Note that hybrid depends on sources.
srs_freep(_srs_hybrid);
srs_freep(_srs_sources);

srs_freep(_srs_clock);

srs_freep(_srs_stages);
srs_freep(_srs_circuit_breaker);

#ifdef SRS_SRT
srs_freep(_srs_srt_sources);
#endif

#ifdef SRS_RTC
srs_freep(_srs_rtc_sources);
srs_freep(_srs_blackhole);
srs_freep(_srs_rtc_manager);
srs_freep(_srs_rtc_dtls_certificate);
#endif
#ifdef SRS_GB28181
srs_freep(_srs_gb_manager);
#endif

srs_freep(_srs_pps_ids);
srs_freep(_srs_pps_fids);
srs_freep(_srs_pps_fids_level0);
srs_freep(_srs_pps_dispose);

srs_freep(_srs_pps_timer);
srs_freep(_srs_pps_conn);
srs_freep(_srs_pps_pub);

#ifdef SRS_RTC
srs_freep(_srs_pps_snack);
srs_freep(_srs_pps_snack2);
srs_freep(_srs_pps_snack3);
srs_freep(_srs_pps_snack4);
srs_freep(_srs_pps_sanack);
srs_freep(_srs_pps_svnack);

srs_freep(_srs_pps_rnack);
srs_freep(_srs_pps_rnack2);
srs_freep(_srs_pps_rhnack);
srs_freep(_srs_pps_rmnack);
#endif

#if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS)
srs_freep(_srs_pps_recvfrom);
srs_freep(_srs_pps_recvfrom_eagain);
srs_freep(_srs_pps_sendto);
srs_freep(_srs_pps_sendto_eagain);

srs_freep(_srs_pps_read);
srs_freep(_srs_pps_read_eagain);
srs_freep(_srs_pps_readv);
srs_freep(_srs_pps_readv_eagain);
srs_freep(_srs_pps_writev);
srs_freep(_srs_pps_writev_eagain);

srs_freep(_srs_pps_recvmsg);
srs_freep(_srs_pps_recvmsg_eagain);
srs_freep(_srs_pps_sendmsg);
srs_freep(_srs_pps_sendmsg_eagain);

srs_freep(_srs_pps_epoll);
srs_freep(_srs_pps_epoll_zero);
srs_freep(_srs_pps_epoll_shake);
srs_freep(_srs_pps_epoll_spin);

srs_freep(_srs_pps_sched_15ms);
srs_freep(_srs_pps_sched_20ms);
srs_freep(_srs_pps_sched_25ms);
srs_freep(_srs_pps_sched_30ms);
srs_freep(_srs_pps_sched_35ms);
srs_freep(_srs_pps_sched_40ms);
srs_freep(_srs_pps_sched_80ms);
srs_freep(_srs_pps_sched_160ms);
srs_freep(_srs_pps_sched_s);
#endif

srs_freep(_srs_pps_clock_15ms);
srs_freep(_srs_pps_clock_20ms);
srs_freep(_srs_pps_clock_25ms);
srs_freep(_srs_pps_clock_30ms);
srs_freep(_srs_pps_clock_35ms);
srs_freep(_srs_pps_clock_40ms);
srs_freep(_srs_pps_clock_80ms);
srs_freep(_srs_pps_clock_160ms);
srs_freep(_srs_pps_timer_s);

#if defined(SRS_DEBUG) && defined(SRS_DEBUG_STATS)
srs_freep(_srs_pps_thread_run);
srs_freep(_srs_pps_thread_idle);
srs_freep(_srs_pps_thread_yield);
srs_freep(_srs_pps_thread_yield2);
#endif

srs_freep(_srs_pps_rpkts);
srs_freep(_srs_pps_addrs);
srs_freep(_srs_pps_fast_addrs);

srs_freep(_srs_pps_spkts);
srs_freep(_srs_pps_objs_msgs);

#ifdef SRS_RTC
srs_freep(_srs_pps_sstuns);
srs_freep(_srs_pps_srtcps);
srs_freep(_srs_pps_srtps);

srs_freep(_srs_pps_rstuns);
srs_freep(_srs_pps_rrtps);
srs_freep(_srs_pps_rrtcps);

srs_freep(_srs_pps_aloss2);

srs_freep(_srs_pps_pli);
srs_freep(_srs_pps_twcc);
srs_freep(_srs_pps_rr);

srs_freep(_srs_pps_objs_rtps);
srs_freep(_srs_pps_objs_rraw);
srs_freep(_srs_pps_objs_rfua);
srs_freep(_srs_pps_objs_rbuf);
srs_freep(_srs_pps_objs_rothers);
#endif

srs_freep(_srs_dvr_async);

#ifdef SRS_APM
srs_freep(_srs_cls);
srs_freep(_srs_apm);
#endif

srs_freep(_srs_reload_err);

// Note that we never free the logging, because it's used after thread terminated.
//srs_freep(_srs_log);
//srs_freep(_srs_config);
//srs_freep(_srs_context);
//srs_freep(_srs_pps_cids_get);
//srs_freep(_srs_pps_cids_set);

// Dispose ST finally, which may be used by other global objects.
srs_st_destroy();
}

SrsThreadMutex::SrsThreadMutex()
{
// https://man7.org/linux/man-pages/man3/pthread_mutexattr_init.3.html
Expand Down
1 change: 0 additions & 1 deletion trunk/src/app/srs_app_threads.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ extern SrsCircuitBreaker* _srs_circuit_breaker;

// Initialize global shared variables cross all threads.
extern srs_error_t srs_global_initialize();
extern void srs_global_dispose();

// The thread mutex wrapper, without error.
class SrsThreadMutex
Expand Down
14 changes: 5 additions & 9 deletions trunk/src/main/srs_main_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,17 +463,17 @@ srs_error_t run_directly_or_daemon()
srs_error_t run_hybrid_server(void* arg);
srs_error_t run_in_thread_pool()
{
#ifdef SRS_SINGLE_THREAD
srs_trace("Run in single thread mode");
return run_hybrid_server(NULL);
#else
srs_error_t err = srs_success;

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

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

// Dispose all global objects, note that we should do this in the hybrid thread, because it may
// depend on the ST when disposing.
srs_global_dispose();

return err;
}

0 comments on commit e0402d6

Please sign in to comment.