Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2015-05-30 14:41:47 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
9dce971d575fbb5d0f5e2c967f74358f41c99009
9dce971d
2 parents
597993d4
223ae194
merge from srs2
显示空白字符变更
内嵌
并排对比
正在显示
18 个修改的文件
包含
394 行增加
和
35 行删除
README.md
trunk/conf/full.conf
trunk/etc/init.d/srs
trunk/src/app/srs_app_config.cpp
trunk/src/app/srs_app_config.hpp
trunk/src/app/srs_app_ffmpeg.cpp
trunk/src/app/srs_app_ffmpeg.hpp
trunk/src/app/srs_app_hls.cpp
trunk/src/app/srs_app_hls.hpp
trunk/src/app/srs_app_ingest.cpp
trunk/src/app/srs_app_ingest.hpp
trunk/src/app/srs_app_server.cpp
trunk/src/app/srs_app_server.hpp
trunk/src/app/srs_app_source.cpp
trunk/src/app/srs_app_source.hpp
trunk/src/app/srs_app_utility.cpp
trunk/src/app/srs_app_utility.hpp
trunk/src/kernel/srs_kernel_error.hpp
README.md
查看文件 @
9dce971
...
...
@@ -250,7 +250,7 @@ Compare SRS with other media server.
| RTMP Edge | Stable | X | X | Stable | X |
| RTMP Backup | Stable | X | X | X | X |
| VHOST | Stable | X | X | Stable | Stable |
| Reload | Stable |
Stable
| X | X | X |
| Reload | Stable |
X
| X | X | X |
| Forward | Stable | X | X | X | X |
| ATC | Stable | X | X | X | X |
...
...
@@ -312,6 +312,7 @@ Remark:
1.
HLS aonly: The HLS audio only streaming delivery.
1.
BW check: The bandwidth check.
1.
Security: To allow or deny stream publish or play.
1.
Reload: Nginx supports reload, but not nginx-rtmp.
## Releases
...
...
@@ -346,6 +347,8 @@ Remark:
*
v3.0, 2015-03-15, fork srs2 and start srs3. 3.0.0
### SRS 2.0 history
*
v2.0, 2015-05-30, fix
[
#209
](
https://github.com/simple-rtmp-server/srs/issues/209
)
cleanup hls when stop and timeout. 2.0.173.
*
v2.0, 2015-05-29, fix
[
#409
](
https://github.com/simple-rtmp-server/srs/issues/409
)
support pure video hls. 2.0.172.
*
v2.0, 2015-05-28, support
[
srs-dolphin
][
srs-dolphin
]
, the multiple-process SRS.
*
v2.0, 2015-05-24, fix
[
#404
](
https://github.com/simple-rtmp-server/srs/issues/404
)
register handler then start http thread. 2.0.167.
...
...
trunk/conf/full.conf
查看文件 @
9dce971
...
...
@@ -618,9 +618,14 @@ vhost with-hls.srs.com {
# h264, vn
# default: h264
hls_vcodec
h264
;
# whether cleanup the old ts files.
# whether cleanup the old
expired
ts files.
# default: on
hls_cleanup
on
;
# the timeout in seconds to dispose the hls,
# dispose is to remove all hls files, m3u8 and ts files.
# when timeout or server terminate, dispose hls.
# default: 300
hls_dispose
300
;
# the max size to notify hls,
# to read max bytes from ts of specified cdn network,
# @remark only used when on_hls_notify is config.
...
...
trunk/etc/init.d/srs
查看文件 @
9dce971
...
...
@@ -109,12 +109,12 @@ stop() {
ok_msg
"Stopping SRS(pid
${
srs_pid
}
)..."
# process exists, try to kill to stop normally
for
((
i
=
0;i<
3
0;i++
))
;
do
for
((
i
=
0;i<
10
0;i++
))
;
do
load_process_info
if
[[
0 -eq
$?
]]
;
then
kill
-s SIGTERM
${
srs_pid
}
2>/dev/null
ret
=
$?
;
if
[[
0 -ne
$ret
]]
;
then
failed_msg
"send signal SIGTERM failed ret=
$ret
"
;
return
$ret
;
fi
sleep 0.
1
sleep 0.
3
else
ok_msg
"SRS stopped by SIGTERM"
# delete the pid file when stop success.
...
...
trunk/src/app/srs_app_config.cpp
查看文件 @
9dce971
...
...
@@ -1564,7 +1564,8 @@ int SrsConfig::check_config()
string
m
=
conf
->
at
(
j
)
->
name
.
c_str
();
if
(
m
!=
"enabled"
&&
m
!=
"hls_entry_prefix"
&&
m
!=
"hls_path"
&&
m
!=
"hls_fragment"
&&
m
!=
"hls_window"
&&
m
!=
"hls_on_error"
&&
m
!=
"hls_storage"
&&
m
!=
"hls_mount"
&&
m
!=
"hls_td_ratio"
&&
m
!=
"hls_aof_ratio"
&&
m
!=
"hls_acodec"
&&
m
!=
"hls_vcodec"
&&
m
!=
"hls_m3u8_file"
&&
m
!=
"hls_ts_file"
&&
m
!=
"hls_ts_floor"
&&
m
!=
"hls_cleanup"
&&
m
!=
"hls_nb_notify"
&&
m
!=
"hls_wait_keyframe"
&&
m
!=
"hls_m3u8_file"
&&
m
!=
"hls_ts_file"
&&
m
!=
"hls_ts_floor"
&&
m
!=
"hls_cleanup"
&&
m
!=
"hls_nb_notify"
&&
m
!=
"hls_wait_keyframe"
&&
m
!=
"hls_dispose"
)
{
ret
=
ERROR_SYSTEM_CONFIG_INVALID
;
srs_error
(
"unsupported vhost hls directive %s, ret=%d"
,
m
.
c_str
(),
ret
);
...
...
@@ -3561,6 +3562,24 @@ bool SrsConfig::get_hls_cleanup(string vhost)
return
SRS_CONF_PERFER_TRUE
(
conf
->
arg0
());
}
int
SrsConfig
::
get_hls_dispose
(
string
vhost
)
{
SrsConfDirective
*
conf
=
get_hls
(
vhost
);
int
DEFAULT
=
300
;
if
(
!
conf
)
{
return
DEFAULT
;
}
conf
=
conf
->
get
(
"hls_dispose"
);
if
(
!
conf
||
conf
->
arg0
().
empty
())
{
return
DEFAULT
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
bool
SrsConfig
::
get_hls_wait_keyframe
(
string
vhost
)
{
SrsConfDirective
*
hls
=
get_hls
(
vhost
);
...
...
trunk/src/app/srs_app_config.hpp
查看文件 @
9dce971
...
...
@@ -985,6 +985,10 @@ public:
*/
virtual
bool
get_hls_cleanup
(
std
::
string
vhost
);
/**
* the timeout to dispose the hls.
*/
virtual
int
get_hls_dispose
(
std
::
string
vhost
);
/**
* whether reap the ts when got keyframe.
*/
virtual
bool
get_hls_wait_keyframe
(
std
::
string
vhost
);
...
...
trunk/src/app/srs_app_ffmpeg.cpp
查看文件 @
9dce971
...
...
@@ -35,6 +35,7 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_config.hpp>
#include <srs_app_utility.hpp>
#ifdef SRS_AUTO_FFMPEG_STUB
...
...
@@ -51,6 +52,7 @@ using namespace std;
SrsFFMPEG
::
SrsFFMPEG
(
std
::
string
ffmpeg_bin
)
{
started
=
false
;
fast_stopped
=
false
;
pid
=
-
1
;
ffmpeg
=
ffmpeg_bin
;
...
...
@@ -402,6 +404,10 @@ int SrsFFMPEG::start()
// child process: ffmpeg encoder engine.
if
(
pid
==
0
)
{
// ignore the SIGINT and SIGTERM
signal
(
SIGINT
,
SIG_IGN
);
signal
(
SIGTERM
,
SIG_IGN
);
// redirect logs to file.
int
log_fd
=
-
1
;
int
flags
=
O_CREAT
|
O_WRONLY
|
O_APPEND
;
...
...
@@ -479,6 +485,11 @@ int SrsFFMPEG::cycle()
return
ret
;
}
// ffmpeg is prepare to stop, donot cycle.
if
(
fast_stopped
)
{
return
ret
;
}
int
status
=
0
;
pid_t
p
=
waitpid
(
pid
,
&
status
,
WNOHANG
);
...
...
@@ -509,24 +520,35 @@ void SrsFFMPEG::stop()
// when rewind, upstream will stop publish(unpublish),
// unpublish event will stop all ffmpeg encoders,
// then publish will start all ffmpeg encoders.
if
(
pid
>
0
)
{
if
(
kill
(
pid
,
SIGKILL
)
<
0
)
{
srs_warn
(
"kill the encoder failed, ignored. pid=%d"
,
pid
);
int
ret
=
srs_kill_forced
(
pid
);
if
(
ret
!=
ERROR_SUCCESS
)
{
srs_warn
(
"ignore kill the encoder failed, pid=%d. ret=%d"
,
pid
,
ret
);
return
;
}
// wait for the ffmpeg to quit.
// ffmpeg will gracefully quit if signal is:
// 1) SIGHUP 2) SIGINT 3) SIGQUIT
// other signals, directly exit(123), for example:
// 9) SIGKILL 15) SIGTERM
int
status
=
0
;
if
(
waitpid
(
pid
,
&
status
,
0
)
<
0
)
{
srs_warn
(
"wait the encoder quit failed, ignored. pid=%d"
,
pid
);
// terminated, set started to false to stop the cycle.
started
=
false
;
}
void
SrsFFMPEG
::
fast_stop
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
started
)
{
return
;
}
srs_trace
(
"stop the encoder success. pid=%d"
,
pid
);
pid
=
-
1
;
if
(
pid
<=
0
)
{
return
;
}
if
(
kill
(
pid
,
SIGTERM
)
<
0
)
{
ret
=
ERROR_SYSTEM_KILL
;
srs_warn
(
"ignore fast stop ffmpeg failed, pid=%d. ret=%d"
,
pid
,
ret
);
return
;
}
return
;
}
#endif
...
...
trunk/src/app/srs_app_ffmpeg.hpp
查看文件 @
9dce971
...
...
@@ -45,6 +45,8 @@ class SrsFFMPEG
{
private
:
bool
started
;
// whether SIGINT send but need to wait or SIGKILL.
bool
fast_stopped
;
pid_t
pid
;
private
:
std
::
string
log_file
;
...
...
@@ -83,7 +85,25 @@ public:
virtual
int
initialize_copy
();
virtual
int
start
();
virtual
int
cycle
();
/**
* send SIGTERM then SIGKILL to ensure the process stopped.
* the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the
* process quit timeout.
* @remark use fast_stop before stop one by one, when got lots of process to quit.
*/
virtual
void
stop
();
public
:
/**
* the fast stop is to send a SIGTERM.
* for example, the ingesters owner lots of FFMPEG, it will take a long time
* to stop one by one, instead the ingesters can fast_stop all FFMPEG, then
* wait one by one to stop, it's more faster.
* @remark user must use stop() to ensure the ffmpeg to stopped.
* @remark we got N processes to stop, compare the time we spend,
* when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N]
* but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
*/
virtual
void
fast_stop
();
};
#endif
...
...
trunk/src/app/srs_app_hls.cpp
查看文件 @
9dce971
...
...
@@ -305,6 +305,37 @@ SrsHlsMuxer::~SrsHlsMuxer()
srs_freep
(
context
);
}
void
SrsHlsMuxer
::
dispose
()
{
if
(
should_write_file
)
{
std
::
vector
<
SrsHlsSegment
*>::
iterator
it
;
for
(
it
=
segments
.
begin
();
it
!=
segments
.
end
();
++
it
)
{
SrsHlsSegment
*
segment
=
*
it
;
if
(
unlink
(
segment
->
full_path
.
c_str
())
<
0
)
{
srs_warn
(
"dispose unlink path failed, file=%s."
,
segment
->
full_path
.
c_str
());
}
srs_freep
(
segment
);
}
segments
.
clear
();
if
(
current
)
{
std
::
string
path
=
current
->
full_path
+
".tmp"
;
if
(
unlink
(
path
.
c_str
())
<
0
)
{
srs_warn
(
"dispose unlink path failed, file=%s"
,
path
.
c_str
());
}
srs_freep
(
current
);
}
if
(
unlink
(
m3u8
.
c_str
())
<
0
)
{
srs_warn
(
"dispose unlink path failed. file=%s"
,
m3u8
.
c_str
());
}
}
// TODO: FIXME: support hls dispose in HTTP cache.
srs_trace
(
"gracefully dispose hls %s"
,
req
?
req
->
get_stream_url
().
c_str
()
:
""
);
}
int
SrsHlsMuxer
::
sequence_no
()
{
return
_sequence_no
;
...
...
@@ -720,6 +751,9 @@ int SrsHlsMuxer::segment_close(string log_desc)
std
::
string
tmp_file
=
current
->
full_path
+
".tmp"
;
if
(
should_write_file
)
{
unlink
(
tmp_file
.
c_str
());
if
(
unlink
(
tmp_file
.
c_str
())
<
0
)
{
srs_warn
(
"drop unlink path failed, file=%s."
,
tmp_file
.
c_str
());
}
}
srs_freep
(
current
);
...
...
@@ -754,7 +788,9 @@ int SrsHlsMuxer::segment_close(string log_desc)
SrsHlsSegment
*
segment
=
segment_to_remove
[
i
];
if
(
hls_cleanup
)
{
unlink
(
segment
->
full_path
.
c_str
());
if
(
unlink
(
segment
->
full_path
.
c_str
())
<
0
)
{
srs_warn
(
"cleanup unlink path failed, file=%s."
,
segment
->
full_path
.
c_str
());
}
}
srs_freep
(
segment
);
...
...
@@ -1085,6 +1121,8 @@ SrsHls::SrsHls()
handler
=
NULL
;
hls_enabled
=
false
;
hls_can_dispose
=
false
;
last_update_time
=
0
;
codec
=
new
SrsAvcAacCodec
();
sample
=
new
SrsCodecSample
();
...
...
@@ -1109,6 +1147,46 @@ SrsHls::~SrsHls()
srs_freep
(
pprint
);
}
void
SrsHls
::
dispose
()
{
if
(
hls_enabled
)
{
on_unpublish
();
}
muxer
->
dispose
();
}
int
SrsHls
::
cycle
()
{
int
ret
=
ERROR_SUCCESS
;
srs_info
(
"hls cycle for source %d"
,
source
->
source_id
());
if
(
last_update_time
<=
0
)
{
last_update_time
=
srs_get_system_time_ms
();
}
if
(
!
_req
)
{
return
ret
;
}
int
hls_dispose
=
_srs_config
->
get_hls_dispose
(
_req
->
vhost
)
*
1000
;
if
(
srs_get_system_time_ms
()
-
last_update_time
<=
hls_dispose
)
{
return
ret
;
}
last_update_time
=
srs_get_system_time_ms
();
if
(
!
hls_can_dispose
)
{
return
ret
;
}
hls_can_dispose
=
false
;
srs_trace
(
"hls cycle to dispose hls %s, timeout=%dms"
,
_req
->
get_stream_url
().
c_str
(),
hls_dispose
);
dispose
();
return
ret
;
}
int
SrsHls
::
initialize
(
SrsSource
*
s
,
ISrsHlsHandler
*
h
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -1127,6 +1205,11 @@ int SrsHls::on_publish(SrsRequest* req)
{
int
ret
=
ERROR_SUCCESS
;
_req
=
req
;
// update the hls time, for hls_dispose.
last_update_time
=
srs_get_system_time_ms
();
// support multiple publish.
if
(
hls_enabled
)
{
return
ret
;
...
...
@@ -1144,6 +1227,9 @@ int SrsHls::on_publish(SrsRequest* req)
// if enabled, open the muxer.
hls_enabled
=
true
;
// ok, the hls can be dispose, or need to be dispose.
hls_can_dispose
=
true
;
// notice the source to get the cached sequence header.
// when reload to start hls, hls will never get the sequence header in stream,
// use the SrsSource.on_hls_start to push the sequence header to HLS.
...
...
@@ -1196,6 +1282,9 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio)
return
ret
;
}
// update the hls time, for hls_dispose.
last_update_time
=
srs_get_system_time_ms
();
SrsSharedPtrMessage
*
audio
=
shared_audio
->
copy
();
SrsAutoFree
(
SrsSharedPtrMessage
,
audio
);
...
...
@@ -1257,6 +1346,9 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video)
return
ret
;
}
// update the hls time, for hls_dispose.
last_update_time
=
srs_get_system_time_ms
();
SrsSharedPtrMessage
*
video
=
shared_video
->
copy
();
SrsAutoFree
(
SrsSharedPtrMessage
,
video
);
...
...
trunk/src/app/srs_app_hls.hpp
查看文件 @
9dce971
...
...
@@ -260,6 +260,8 @@ public:
SrsHlsMuxer
();
virtual
~
SrsHlsMuxer
();
public
:
virtual
void
dispose
();
public
:
virtual
int
sequence_no
();
virtual
std
::
string
ts_url
();
virtual
double
duration
();
...
...
@@ -379,7 +381,11 @@ private:
SrsHlsCache
*
hls_cache
;
ISrsHlsHandler
*
handler
;
private
:
SrsRequest
*
_req
;
bool
hls_enabled
;
bool
hls_can_dispose
;
int64_t
last_update_time
;
private
:
SrsSource
*
source
;
SrsAvcAacCodec
*
codec
;
SrsCodecSample
*
sample
;
...
...
@@ -403,6 +409,9 @@ public:
SrsHls
();
virtual
~
SrsHls
();
public
:
virtual
void
dispose
();
virtual
int
cycle
();
public
:
/**
* initialize the hls by handler and source.
*/
...
...
trunk/src/app/srs_app_ingest.cpp
查看文件 @
9dce971
...
...
@@ -51,6 +51,11 @@ SrsIngesterFFMPEG::~SrsIngesterFFMPEG()
srs_freep
(
ffmpeg
);
}
void
SrsIngesterFFMPEG
::
fast_stop
()
{
ffmpeg
->
fast_stop
();
}
SrsIngester
::
SrsIngester
()
{
_srs_config
->
subscribe
(
this
);
...
...
@@ -159,6 +164,23 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
return
ret
;
}
void
SrsIngester
::
dispose
()
{
// first, use fast stop to notice all FFMPEG to quit gracefully.
std
::
vector
<
SrsIngesterFFMPEG
*>::
iterator
it
;
for
(
it
=
ingesters
.
begin
();
it
!=
ingesters
.
end
();
++
it
)
{
SrsIngesterFFMPEG
*
ingester
=
*
it
;
ingester
->
fast_stop
();
}
if
(
!
ingesters
.
empty
())
{
srs_trace
(
"fast stop all ingesters ok."
);
}
// then, use stop to wait FFMPEG quit one by one and send SIGKILL if needed.
stop
();
}
void
SrsIngester
::
stop
()
{
pthread
->
stop
();
...
...
trunk/src/app/srs_app_ingest.hpp
查看文件 @
9dce971
...
...
@@ -52,6 +52,9 @@ public:
SrsIngesterFFMPEG
(
SrsFFMPEG
*
_ffmpeg
,
std
::
string
_vhost
,
std
::
string
_id
);
virtual
~
SrsIngesterFFMPEG
();
// @see SrsFFMPEG.fast_stop().
virtual
void
fast_stop
();
};
/**
...
...
@@ -70,6 +73,8 @@ public:
SrsIngester
();
virtual
~
SrsIngester
();
public
:
virtual
void
dispose
();
public
:
virtual
int
start
();
virtual
void
stop
();
// interface ISrsReusableThreadHandler.
...
...
trunk/src/app/srs_app_server.cpp
查看文件 @
9dce971
...
...
@@ -480,6 +480,7 @@ SrsServer::SrsServer()
{
signal_reload
=
false
;
signal_gmc_stop
=
false
;
signal_gracefully_quit
=
false
;
pid_fd
=
-
1
;
signal_manager
=
NULL
;
...
...
@@ -519,7 +520,7 @@ void SrsServer::destroy()
close_listeners
(
SrsListenerHttpStream
);
#ifdef SRS_AUTO_INGEST
ingester
->
stop
();
ingester
->
dispose
();
#endif
#ifdef SRS_AUTO_HTTP_API
...
...
@@ -555,6 +556,21 @@ void SrsServer::destroy()
// and segment fault.
}
void
SrsServer
::
dispose
()
{
_srs_config
->
unsubscribe
(
this
);
#ifdef SRS_AUTO_INGEST
ingester
->
dispose
();
srs_trace
(
"gracefully dispose ingesters"
);
#endif
SrsSource
::
dispose_all
();
srs_trace
(
"gracefully dispose sources"
);
srs_trace
(
"terminate server"
);
}
int
SrsServer
::
initialize
(
ISrsServerCycle
*
cycle_handler
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -831,6 +847,7 @@ int SrsServer::cycle()
srs_warn
(
"system quit"
);
#else
srs_warn
(
"main cycle terminated, system quit normally."
);
dispose
();
exit
(
0
);
#endif
...
...
@@ -877,9 +894,9 @@ void SrsServer::on_signal(int signo)
return
;
}
if
(
signo
==
SIGTERM
)
{
srs_trace
(
"user terminate program"
);
exit
(
0
);
if
(
signo
==
SIGTERM
&&
!
signal_gracefully_quit
)
{
srs_trace
(
"user terminate program, gracefully quit."
);
signal_gracefully_quit
=
true
;
return
;
}
}
...
...
@@ -903,7 +920,7 @@ int SrsServer::do_cycle()
// the deamon thread, update the time cache
while
(
true
)
{
if
(
handler
&&
(
ret
=
handler
->
on_cycle
(
conns
.
size
()))
!=
ERROR_SUCCESS
){
if
(
handler
&&
(
ret
=
handler
->
on_cycle
(
(
int
)
conns
.
size
()))
!=
ERROR_SUCCESS
){
srs_error
(
"cycle handle failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
@@ -918,11 +935,17 @@ int SrsServer::do_cycle()
for
(
int
i
=
0
;
i
<
temp_max
;
i
++
)
{
st_usleep
(
SRS_SYS_CYCLE_INTERVAL
*
1000
);
// for gperf heap checker,
// @see: research/gperftools/heap-checker/heap_checker.cc
// if user interrupt the program, exit to check mem leak.
// but, if gperf, use reload to ensure main return normally,
// because directly exit will cause core-dump.
// gracefully quit for SIGINT or SIGTERM.
if
(
signal_gracefully_quit
)
{
srs_trace
(
"cleanup for gracefully terminate."
);
return
ret
;
}
// for gperf heap checker,
// @see: research/gperftools/heap-checker/heap_checker.cc
// if user interrupt the program, exit to check mem leak.
// but, if gperf, use reload to ensure main return normally,
// because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
if
(
signal_gmc_stop
)
{
srs_warn
(
"gmc got singal to stop server."
);
...
...
@@ -930,6 +953,7 @@ int SrsServer::do_cycle()
}
#endif
// do reload the config.
if
(
signal_reload
)
{
signal_reload
=
false
;
srs_info
(
"get signal reload, to reload the config."
);
...
...
@@ -941,6 +965,11 @@ int SrsServer::do_cycle()
srs_trace
(
"reload config success."
);
}
// notice the stream sources to cycle.
if
((
ret
=
SrsSource
::
cycle_all
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// update the cache time
if
((
i
%
SRS_SYS_TIME_RESOLUTION_MS_TIMES
)
==
0
)
{
srs_info
(
"update current time cache."
);
...
...
trunk/src/app/srs_app_server.hpp
查看文件 @
9dce971
...
...
@@ -275,16 +275,22 @@ private:
*/
bool
signal_reload
;
bool
signal_gmc_stop
;
bool
signal_gracefully_quit
;
public
:
SrsServer
();
virtual
~
SrsServer
();
p
ublic
:
p
rivate
:
/**
* the destroy is for gmc to analysis the memory leak,
* if not destroy global/static data, the gmc will warning memory leak.
* in service, server never destroy, directly exit when restart.
*/
virtual
void
destroy
();
/**
* when SIGTERM, SRS should do cleanup, for example,
* to stop all ingesters, cleanup HLS and dvr.
*/
virtual
void
dispose
();
// server startup workflow, @see run_master()
public:
virtual
int
initialize
(
ISrsServerCycle
*
cycle_handler
);
...
...
trunk/src/app/srs_app_source.cpp
查看文件 @
9dce971
...
...
@@ -771,6 +771,32 @@ SrsSource* SrsSource::fetch(std::string vhost, std::string app, std::string stre
return
source
;
}
void
SrsSource
::
dispose_all
()
{
std
::
map
<
std
::
string
,
SrsSource
*>::
iterator
it
;
for
(
it
=
pool
.
begin
();
it
!=
pool
.
end
();
++
it
)
{
SrsSource
*
source
=
it
->
second
;
source
->
dispose
();
}
return
;
}
int
SrsSource
::
cycle_all
()
{
int
ret
=
ERROR_SUCCESS
;
// TODO: FIXME: support remove dead source for a long time.
std
::
map
<
std
::
string
,
SrsSource
*>::
iterator
it
;
for
(
it
=
pool
.
begin
();
it
!=
pool
.
end
();
++
it
)
{
SrsSource
*
source
=
it
->
second
;
if
((
ret
=
source
->
cycle
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
void
SrsSource
::
destroy
()
{
std
::
map
<
std
::
string
,
SrsSource
*>::
iterator
it
;
...
...
@@ -909,6 +935,26 @@ SrsSource::~SrsSource()
srs_freep
(
_req
);
}
void
SrsSource
::
dispose
()
{
#ifdef SRS_AUTO_HLS
hls
->
dispose
();
#endif
}
int
SrsSource
::
cycle
()
{
int
ret
=
ERROR_SUCCESS
;
#ifdef SRS_AUTO_HLS
if
((
ret
=
hls
->
cycle
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
#endif
return
ret
;
}
int
SrsSource
::
initialize
(
SrsRequest
*
r
,
ISrsSourceHandler
*
h
,
ISrsHlsHandler
*
hh
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
trunk/src/app/srs_app_source.hpp
查看文件 @
9dce971
...
...
@@ -411,6 +411,11 @@ public:
*/
static
SrsSource
*
fetch
(
std
::
string
vhost
,
std
::
string
app
,
std
::
string
stream
);
/**
* dispose and cycle all sources.
*/
static
void
dispose_all
();
static
int
cycle_all
();
/**
* when system exit, destroy the sources,
* for gmc to analysis mem leaks.
*/
...
...
@@ -486,6 +491,9 @@ private:
public
:
SrsSource
();
virtual
~
SrsSource
();
public
:
virtual
void
dispose
();
virtual
int
cycle
();
// initialize, get and setter.
public:
/**
...
...
trunk/src/app/srs_app_utility.cpp
查看文件 @
9dce971
...
...
@@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <unistd.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <signal.h>
#ifdef SRS_OSX
#include <sys/sysctl.h>
...
...
@@ -43,6 +44,9 @@ using namespace std;
#include <srs_app_json.hpp>
#include <srs_kernel_stream.hpp>
// the longest time to wait for a process to quit.
#define SRS_PROCESS_QUIT_TIMEOUT_MS 1000
int
srs_socket_connect
(
string
server
,
int
port
,
int64_t
timeout
,
st_netfd_t
*
pstfd
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -222,6 +226,62 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port)
port
=
::
atoi
(
the_port
.
c_str
());
}
int
srs_kill_forced
(
int
&
pid
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
pid
<=
0
)
{
return
ret
;
}
// first, try kill by SIGTERM.
if
(
kill
(
pid
,
SIGTERM
)
<
0
)
{
return
ERROR_SYSTEM_KILL
;
}
// wait to quit.
srs_trace
(
"send SIGTERM to pid=%d"
,
pid
);
for
(
int
i
=
0
;
i
<
SRS_PROCESS_QUIT_TIMEOUT_MS
/
10
;
i
++
)
{
int
status
=
0
;
pid_t
qpid
=
-
1
;
if
((
qpid
=
waitpid
(
pid
,
&
status
,
WNOHANG
))
<
0
)
{
return
ERROR_SYSTEM_KILL
;
}
// 0 is not quit yet.
if
(
qpid
==
0
)
{
st_usleep
(
10
*
1000
);
continue
;
}
// killed, set pid to -1.
srs_trace
(
"SIGTERM stop process pid=%d ok."
,
pid
);
pid
=
-
1
;
return
ret
;
}
// then, try kill by SIGKILL.
if
(
kill
(
pid
,
SIGKILL
)
<
0
)
{
return
ERROR_SYSTEM_KILL
;
}
// wait for the process to quit.
// for example, ffmpeg will gracefully quit if signal is:
// 1) SIGHUP 2) SIGINT 3) SIGQUIT
// other signals, directly exit(123), for example:
// 9) SIGKILL 15) SIGTERM
int
status
=
0
;
if
(
waitpid
(
pid
,
&
status
,
0
)
<
0
)
{
return
ERROR_SYSTEM_KILL
;
}
srs_trace
(
"SIGKILL stop process pid=%d ok."
,
pid
);
pid
=
-
1
;
return
ret
;
}
static
SrsRusage
_srs_system_rusage
;
SrsRusage
::
SrsRusage
()
...
...
@@ -422,7 +482,7 @@ void srs_update_proc_stat()
// @see https://github.com/simple-rtmp-server/srs/issues/397
static
int
user_hz
=
0
;
if
(
user_hz
<=
0
)
{
user_hz
=
sysconf
(
_SC_CLK_TCK
);
user_hz
=
(
int
)
sysconf
(
_SC_CLK_TCK
);
srs_trace
(
"USER_HZ=%d"
,
user_hz
);
srs_assert
(
user_hz
>
0
);
}
...
...
@@ -646,12 +706,12 @@ void srs_update_disk_stat()
if
(
o
.
pgpgin
>
0
&&
r
.
pgpgin
>
o
.
pgpgin
&&
duration_ms
>
0
)
{
// KBps = KB * 1000 / ms = KB/s
r
.
in_KBps
=
(
r
.
pgpgin
-
o
.
pgpgin
)
*
1000
/
duration_ms
;
r
.
in_KBps
=
(
int
)((
r
.
pgpgin
-
o
.
pgpgin
)
*
1000
/
duration_ms
)
;
}
if
(
o
.
pgpgout
>
0
&&
r
.
pgpgout
>
o
.
pgpgout
&&
duration_ms
>
0
)
{
// KBps = KB * 1000 / ms = KB/s
r
.
out_KBps
=
(
r
.
pgpgout
-
o
.
pgpgout
)
*
1000
/
duration_ms
;
r
.
out_KBps
=
(
int
)((
r
.
pgpgout
-
o
.
pgpgout
)
*
1000
/
duration_ms
)
;
}
}
...
...
@@ -771,8 +831,8 @@ SrsCpuInfo* srs_get_cpuinfo()
// initialize cpu info.
cpu
=
new
SrsCpuInfo
();
cpu
->
ok
=
true
;
cpu
->
nb_processors
=
sysconf
(
_SC_NPROCESSORS_CONF
);
cpu
->
nb_processors_online
=
sysconf
(
_SC_NPROCESSORS_ONLN
);
cpu
->
nb_processors
=
(
int
)
sysconf
(
_SC_NPROCESSORS_CONF
);
cpu
->
nb_processors_online
=
(
int
)
sysconf
(
_SC_NPROCESSORS_ONLN
);
return
cpu
;
}
...
...
trunk/src/app/srs_app_utility.hpp
查看文件 @
9dce971
...
...
@@ -80,6 +80,14 @@ extern std::string srs_path_build_timestamp(std::string template_path);
extern
void
srs_parse_endpoint
(
std
::
string
ip_port
,
std
::
string
&
ip
,
std
::
string
&
port
);
extern
void
srs_parse_endpoint
(
std
::
string
ip_port
,
std
::
string
&
ip
,
int
&
port
);
/**
* kill the pid by SIGINT, then wait to quit,
* kill the pid by SIGKILL again when exceed the timeout.
* @param pid the pid to kill. ignore for -1. set to -1 when killed.
* @return an int error code.
*/
extern
int
srs_kill_forced
(
int
&
pid
);
// current process resouce usage.
// @see: man getrusage
class
SrsRusage
...
...
trunk/src/kernel/srs_kernel_error.hpp
查看文件 @
9dce971
...
...
@@ -96,6 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_SYSTEM_TIME 1055
#define ERROR_SYSTEM_DIR_EXISTS 1056
#define ERROR_SYSTEM_CREATE_DIR 1057
#define ERROR_SYSTEM_KILL 1058
///////////////////////////////////////////////////////
// RTMP protocol error.
...
...
请
注册
或
登录
后发表评论