mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
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 <suzp1984@gmail.com>
This commit is contained in:
parent
cc6db250fb
commit
f8319d6b6d
11 changed files with 89 additions and 161 deletions
|
@ -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);
|
||||
|
@ -1097,7 +1102,6 @@ srs_error_t SrsGoApiTcmalloc::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
|||
#endif
|
||||
|
||||
#ifdef SRS_VALGRIND
|
||||
|
||||
SrsGoApiValgrind::SrsGoApiValgrind()
|
||||
{
|
||||
trd_ = NULL;
|
||||
|
@ -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();
|
||||
|
|
|
@ -233,6 +233,17 @@ public:
|
|||
};
|
||||
#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:
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 6
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 150
|
||||
#define VERSION_REVISION 151
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 9
|
||||
#define VERSION_REVISION 10
|
||||
|
||||
#endif
|
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue