1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Cleanup server for GMC, by WaitGroup to destroy. (#2247). v4.0.206

This commit is contained in:
winlin 2021-11-17 08:23:32 +08:00
parent 73c1392748
commit 63da0dca92
18 changed files with 114 additions and 42 deletions

View file

@ -44,7 +44,7 @@ gtest-1.6.0.zip
gperftools-2.1.zip gperftools-2.1.zip
* gperf tools for performance benchmark. * gperf tools for performance benchmark.
* https://code.google.com/p/gperftools/downloads/list * https://github.com/gperftools/gperftools/releases
st-srs st-srs
st-1.9.zip st-1.9.zip

View file

@ -580,7 +580,7 @@ function check_option_conflicts() {
fi fi
if [[ $SRS_GPERF_MC = YES && $SRS_GPERF_MP = YES ]]; then if [[ $SRS_GPERF_MC = YES && $SRS_GPERF_MP = YES ]]; then
echo "gperf-mc not compatible with gperf-mp, see: ./configure --help"; echo "gperf-mc not compatible with gperf-mp, see: ./configure --help";
echo "@see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html"; echo "@see: https://gperftools.github.io/gperftools/heap_checker.html";
echo "Note that since the heap-checker uses the heap-profiling framework internally, it is not possible to run both the heap-checker and heap profiler at the same time"; echo "Note that since the heap-checker uses the heap-profiling framework internally, it is not possible to run both the heap-checker and heap profiler at the same time";
__check_ok=NO __check_ok=NO
fi fi

View file

@ -34,7 +34,7 @@ BLACK="\\${BLACK}"
echo -e "\${GREEN}The build summary:\${BLACK}" echo -e "\${GREEN}The build summary:\${BLACK}"
echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}" echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
echo -e " \${GREEN}For SRS benchmark, gperf, gprof and valgrind, please read:\${BLACK}" echo -e " \${GREEN}For SRS benchmark, gperf, gprof and valgrind, please read:\${BLACK}"
echo -e " \${GREEN} http://blog.csdn.net/win_lin/article/details/53503869\${BLACK}" echo -e " \${GREEN} https://www.jianshu.com/p/6d4a89359352\${BLACK}"
echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}" echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
echo -e " |\${GREEN}The main server usage: ./objs/srs -c conf/srs.conf, start the srs server\${BLACK}" echo -e " |\${GREEN}The main server usage: ./objs/srs -c conf/srs.conf, start the srs server\${BLACK}"
echo -e " | ${SrsHlsSummaryColor}About HLS, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}" echo -e " | ${SrsHlsSummaryColor}About HLS, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}"

View file

@ -8,6 +8,7 @@ The changelog for SRS.
## SRS 4.0 Changelog ## SRS 4.0 Changelog
* v4.0, 2021-12-26, Fix [#2247](https://github.com/ossrs/srs/pull/2247): Cleanup server for GMC, by WaitGroup to destroy. (#2247). v4.0.212
* v4.0, 2021-12-25, For [#2809](https://github.com/ossrs/srs/issues/2809), HTTP: Fix 2GB+ mp4/flv file downloading error. (#2809)(#2780)(#2781). v4.0.211 * v4.0, 2021-12-25, For [#2809](https://github.com/ossrs/srs/issues/2809), HTTP: Fix 2GB+ mp4/flv file downloading error. (#2809)(#2780)(#2781). v4.0.211
* v4.0, 2021-12-23, For [#2800](https://github.com/ossrs/srs/issues/2800), Fix bug for large mp4(5G+) offset. (#2800). v4.0.210 * v4.0, 2021-12-23, For [#2800](https://github.com/ossrs/srs/issues/2800), Fix bug for large mp4(5G+) offset. (#2800). v4.0.210
* v4.0, 2021-12-23, For [#2807](https://github.com/ossrs/srs/issues/2807), Fix bug for HLS log printing. (#2807). v4.0.209 * v4.0, 2021-12-23, For [#2807](https://github.com/ossrs/srs/issues/2807), Fix bug for HLS log printing. (#2807). v4.0.209

View file

@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
/** /**
@see: http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html @see: https://gperftools.github.io/gperftools/cpuprofile.html
config srs with gperf(to make gperftools): config srs with gperf(to make gperftools):
./configure --with-gperf --jobs=3 ./configure --with-gperf --jobs=3
set the pprof path if not set: set the pprof path if not set:

View file

@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
/** /**
@see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html @see: https://gperftools.github.io/gperftools/heap_checker.html
config srs with gperf(to make gperftools): config srs with gperf(to make gperftools):
./configure --with-gperf --jobs=3 ./configure --with-gperf --jobs=3
set the pprof path if not set: set the pprof path if not set:

View file

@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// //
/** /**
@see: http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html @see: https://gperftools.github.io/gperftools/heapprofile.html
config srs with gperf(to make gperftools): config srs with gperf(to make gperftools):
./configure --with-gperf --jobs=3 ./configure --with-gperf --jobs=3
set the pprof path if not set: set the pprof path if not set:

View file

@ -136,7 +136,7 @@ srs_error_t SrsServerAdapter::initialize()
return err; return err;
} }
srs_error_t SrsServerAdapter::run() srs_error_t SrsServerAdapter::run(SrsWaitGroup* wg)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
@ -173,7 +173,7 @@ srs_error_t SrsServerAdapter::run()
return srs_error_wrap(err, "ingest"); return srs_error_wrap(err, "ingest");
} }
if ((err = srs->start()) != srs_success) { if ((err = srs->start(wg)) != srs_success) {
return srs_error_wrap(err, "start"); return srs_error_wrap(err, "start");
} }
@ -182,6 +182,7 @@ srs_error_t SrsServerAdapter::run()
void SrsServerAdapter::stop() void SrsServerAdapter::stop()
{ {
srs->stop();
} }
SrsServer* SrsServerAdapter::instance() SrsServer* SrsServerAdapter::instance()
@ -264,17 +265,20 @@ srs_error_t SrsHybridServer::run()
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
// Wait for all servers which need to do cleanup.
SrsWaitGroup wg;
vector<ISrsHybridServer*>::iterator it; vector<ISrsHybridServer*>::iterator it;
for (it = servers.begin(); it != servers.end(); ++it) { for (it = servers.begin(); it != servers.end(); ++it) {
ISrsHybridServer* server = *it; ISrsHybridServer* server = *it;
if ((err = server->run()) != srs_success) { if ((err = server->run(&wg)) != srs_success) {
return srs_error_wrap(err, "run server"); return srs_error_wrap(err, "run server");
} }
} }
// Wait for all server to quit. // Wait for all server to quit.
srs_usleep(SRS_UTIME_NO_TIMEOUT); wg.wait();
return err; return err;
} }

View file

@ -14,6 +14,7 @@
#include <srs_app_hourglass.hpp> #include <srs_app_hourglass.hpp>
class SrsServer; class SrsServer;
class SrsWaitGroup;
// The hibrid server interfaces, we could register many servers. // The hibrid server interfaces, we could register many servers.
class ISrsHybridServer class ISrsHybridServer
@ -25,7 +26,7 @@ public:
// Only ST initialized before each server, we could fork processes as such. // Only ST initialized before each server, we could fork processes as such.
virtual srs_error_t initialize() = 0; virtual srs_error_t initialize() = 0;
// Run each server, should never block except the SRS master server. // Run each server, should never block except the SRS master server.
virtual srs_error_t run() = 0; virtual srs_error_t run(SrsWaitGroup* wg) = 0;
// Stop each server, should do cleanup, for example, kill processes forked by server. // Stop each server, should do cleanup, for example, kill processes forked by server.
virtual void stop() = 0; virtual void stop() = 0;
}; };
@ -40,7 +41,7 @@ public:
virtual ~SrsServerAdapter(); virtual ~SrsServerAdapter();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual srs_error_t run(); virtual srs_error_t run(SrsWaitGroup* wg);
virtual void stop(); virtual void stop();
public: public:
virtual SrsServer* instance(); virtual SrsServer* instance();

View file

@ -295,11 +295,11 @@ void SrsRtcServer::set_handler(ISrsRtcServerHandler* h)
void SrsRtcServer::set_hijacker(ISrsRtcServerHijacker* h) void SrsRtcServer::set_hijacker(ISrsRtcServerHijacker* h)
{ {
hijacker = h; hijacker = h;
} }
srs_error_t SrsRtcServer::exec_async_work(ISrsAsyncCallTask * t) srs_error_t SrsRtcServer::exec_async_work(ISrsAsyncCallTask * t)
{ {
return async->execute(t); return async->execute(t);
} }
srs_error_t SrsRtcServer::listen_udp() srs_error_t SrsRtcServer::listen_udp()
@ -698,7 +698,7 @@ srs_error_t RtcServerAdapter::initialize()
return err; return err;
} }
srs_error_t RtcServerAdapter::run() srs_error_t RtcServerAdapter::run(SrsWaitGroup* wg)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;

View file

@ -26,6 +26,7 @@ class SrsRequest;
class SrsSdp; class SrsSdp;
class SrsRtcSource; class SrsRtcSource;
class SrsResourceManager; class SrsResourceManager;
class SrsWaitGroup;
// The UDP black hole, for developer to use wireshark to catch plaintext packets. // The UDP black hole, for developer to use wireshark to catch plaintext packets.
// For example, server receive UDP packets at udp://8000, and forward the plaintext packet to black hole, // For example, server receive UDP packets at udp://8000, and forward the plaintext packet to black hole,
@ -137,7 +138,7 @@ public:
virtual ~RtcServerAdapter(); virtual ~RtcServerAdapter();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual srs_error_t run(); virtual srs_error_t run(SrsWaitGroup* wg);
virtual void stop(); virtual void stop();
}; };

View file

@ -242,6 +242,8 @@ SrsSignalManager::SrsSignalManager(SrsServer* s)
SrsSignalManager::~SrsSignalManager() SrsSignalManager::~SrsSignalManager()
{ {
srs_freep(trd);
srs_close_stfd(signal_read_stfd); srs_close_stfd(signal_read_stfd);
if (sig_pipe[0] > 0) { if (sig_pipe[0] > 0) {
@ -250,8 +252,6 @@ SrsSignalManager::~SrsSignalManager()
if (sig_pipe[1] > 0) { if (sig_pipe[1] > 0) {
::close(sig_pipe[1]); ::close(sig_pipe[1]);
} }
srs_freep(trd);
} }
srs_error_t SrsSignalManager::initialize() srs_error_t SrsSignalManager::initialize()
@ -528,6 +528,7 @@ SrsServer::SrsServer()
ingester = new SrsIngester(); ingester = new SrsIngester();
trd_ = new SrsSTCoroutine("srs", this, _srs_context->get_id()); trd_ = new SrsSTCoroutine("srs", this, _srs_context->get_id());
timer_ = NULL; timer_ = NULL;
wg_ = NULL;
} }
SrsServer::~SrsServer() SrsServer::~SrsServer()
@ -890,7 +891,7 @@ srs_error_t SrsServer::ingest()
return err; return err;
} }
srs_error_t SrsServer::start() srs_error_t SrsServer::start(SrsWaitGroup* wg)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
@ -906,31 +907,25 @@ srs_error_t SrsServer::start()
return srs_error_wrap(err, "tick"); return srs_error_wrap(err, "tick");
} }
// OK, we start SRS server.
wg_ = wg;
wg->add(1);
return err; return err;
} }
srs_error_t SrsServer::cycle() void SrsServer::stop()
{ {
srs_error_t err = srs_success;
// Start the inotify auto reload by watching config file.
SrsInotifyWorker inotify(this);
if ((err = inotify.start()) != srs_success) {
return srs_error_wrap(err, "start inotify");
}
// Do server main cycle.
err = do_cycle();
#ifdef SRS_GPERF_MC #ifdef SRS_GPERF_MC
destroy(); destroy();
// remark, for gmc, never invoke the exit(). // remark, for gmc, never invoke the exit().
srs_warn("sleep a long time for system st-threads to cleanup."); srs_warn("sleep a long time for system st-threads to cleanup.");
srs_usleep(3 * 1000 * 1000); srs_usleep(3 * 1000 * 1000);
srs_warn("system quit"); srs_warn("system quit");
return err; // For GCM, cleanup done.
return;
#endif #endif
// quit normally. // quit normally.
@ -949,12 +944,27 @@ srs_error_t SrsServer::cycle()
} }
srs_trace("srs terminated"); srs_trace("srs terminated");
// for valgrind to detect. // for valgrind to detect.
srs_freep(_srs_config); srs_freep(_srs_config);
srs_freep(_srs_log); srs_freep(_srs_log);
}
exit(0); srs_error_t SrsServer::cycle()
{
srs_error_t err = srs_success;
// Start the inotify auto reload by watching config file.
SrsInotifyWorker inotify(this);
if ((err = inotify.start()) != srs_success) {
return srs_error_wrap(err, "start inotify");
}
// Do server main cycle.
err = do_cycle();
// OK, SRS server is done.
wg_->done();
return err; return err;
} }

View file

@ -35,6 +35,7 @@ class SrsTcpListener;
class SrsAppCasterFlv; class SrsAppCasterFlv;
class SrsResourceManager; class SrsResourceManager;
class SrsLatestVersion; class SrsLatestVersion;
class SrsWaitGroup;
// The listener type for server to identify the connection, // The listener type for server to identify the connection,
// that is, use different type to process the connection. // that is, use different type to process the connection.
@ -204,6 +205,7 @@ private:
SrsResourceManager* conn_manager; SrsResourceManager* conn_manager;
SrsCoroutine* trd_; SrsCoroutine* trd_;
SrsHourGlass* timer_; SrsHourGlass* timer_;
SrsWaitGroup* wg_;
private: private:
// The pid file fd, lock the file write when server is running. // The pid file fd, lock the file write when server is running.
// @remark the init.d script should cleanup the pid file, when stop service, // @remark the init.d script should cleanup the pid file, when stop service,
@ -252,7 +254,9 @@ public:
virtual srs_error_t register_signal(); virtual srs_error_t register_signal();
virtual srs_error_t http_handle(); virtual srs_error_t http_handle();
virtual srs_error_t ingest(); virtual srs_error_t ingest();
virtual srs_error_t start(); public:
virtual srs_error_t start(SrsWaitGroup* wg);
void stop();
// interface ISrsCoroutineHandler // interface ISrsCoroutineHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();

View file

@ -297,3 +297,35 @@ void* SrsFastCoroutine::pfn(void* arg)
return (void*)err; return (void*)err;
} }
SrsWaitGroup::SrsWaitGroup()
{
nn_ = 0;
done_ = srs_cond_new();
}
SrsWaitGroup::~SrsWaitGroup()
{
wait();
srs_cond_destroy(done_);
}
void SrsWaitGroup::add(int n)
{
nn_ += n;
}
void SrsWaitGroup::done()
{
nn_--;
if (nn_ <= 0) {
srs_cond_signal(done_);
}
}
void SrsWaitGroup::wait()
{
if (nn_ > 0) {
srs_cond_wait(done_);
}
}

View file

@ -189,5 +189,23 @@ private:
static void* pfn(void* arg); static void* pfn(void* arg);
}; };
// Like goroytine sync.WaitGroup.
class SrsWaitGroup
{
private:
int nn_;
srs_cond_t done_;
public:
SrsWaitGroup();
virtual ~SrsWaitGroup();
public:
// When start for n coroutines.
void add(int n);
// When coroutine is done.
void done();
// Wait for all corotine to be done.
void wait();
};
#endif #endif

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 4 #define VERSION_MAJOR 4
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 211 #define VERSION_REVISION 212
#endif #endif

View file

@ -323,7 +323,7 @@ srs_error_t SrtServerAdapter::initialize()
return err; return err;
} }
srs_error_t SrtServerAdapter::run() srs_error_t SrtServerAdapter::run(SrsWaitGroup* wg)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;

View file

@ -17,6 +17,7 @@
#include <srs_app_hybrid.hpp> #include <srs_app_hybrid.hpp>
class srt_handle; class srt_handle;
class SrsWaitGroup;
class srt_server { class srt_server {
public: public:
@ -59,7 +60,7 @@ public:
virtual ~SrtServerAdapter(); virtual ~SrtServerAdapter();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual srs_error_t run(); virtual srs_error_t run(SrsWaitGroup* wg);
virtual void stop(); virtual void stop();
}; };