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
2014-05-03 22:59:21 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
96a5c7b1abb3252e796fc2298e4d6793998478f2
96a5c7b1
1 parent
9a1c4782
fix mem leak of encoder, edge and source. add destroy for gmc to detect mem leak. to 0.9.89
隐藏空白字符变更
内嵌
并排对比
正在显示
11 个修改的文件
包含
144 行增加
和
89 行删除
trunk/src/app/srs_app_conn.cpp
trunk/src/app/srs_app_conn.hpp
trunk/src/app/srs_app_edge.cpp
trunk/src/app/srs_app_encoder.cpp
trunk/src/app/srs_app_rtmp_conn.cpp
trunk/src/app/srs_app_server.cpp
trunk/src/app/srs_app_source.cpp
trunk/src/app/srs_app_source.hpp
trunk/src/app/srs_app_thread.cpp
trunk/src/app/srs_app_thread.hpp
trunk/src/core/srs_core.hpp
trunk/src/app/srs_app_conn.cpp
查看文件 @
96a5c7b
...
...
@@ -35,26 +35,59 @@ SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
server
=
srs_server
;
stfd
=
client_stfd
;
connection_id
=
0
;
pthread
=
new
SrsThread
(
this
,
0
);
}
SrsConnection
::~
SrsConnection
()
{
srs_freepa
(
ip
);
srs_close_stfd
(
stfd
);
stop
();
}
int
SrsConnection
::
start
()
{
return
pthread
->
start
();
}
int
SrsConnection
::
cycle
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
st_thread_create
(
cycle_thread
,
this
,
0
,
0
)
==
NULL
)
{
ret
=
ERROR_ST_CREATE_CYCLE_THREAD
;
srs_error
(
"st_thread_create conn cycle thread error. ret=%d"
,
ret
);
return
ret
;
_srs_context
->
generate_id
();
connection_id
=
_srs_context
->
get_id
();
ret
=
do_cycle
();
// if socket io error, set to closed.
if
(
srs_is_client_gracefully_close
(
ret
))
{
ret
=
ERROR_SOCKET_CLOSED
;
}
srs_verbose
(
"create st conn cycle thread success."
);
return
ret
;
// success.
if
(
ret
==
ERROR_SUCCESS
)
{
srs_trace
(
"client process normally finished. ret=%d"
,
ret
);
}
// client close peer.
if
(
ret
==
ERROR_SOCKET_CLOSED
)
{
srs_warn
(
"client disconnect peer. ret=%d"
,
ret
);
}
// set loop to stop to quit.
pthread
->
stop_loop
();
return
ERROR_SUCCESS
;
}
void
SrsConnection
::
on_thread_stop
()
{
server
->
remove
(
this
);
}
void
SrsConnection
::
stop
()
{
srs_close_stfd
(
stfd
);
srs_freep
(
pthread
);
srs_freepa
(
ip
);
}
int
SrsConnection
::
get_peer_ip
()
...
...
@@ -92,40 +125,3 @@ int SrsConnection::get_peer_ip()
return
ret
;
}
void
SrsConnection
::
cycle
()
{
int
ret
=
ERROR_SUCCESS
;
_srs_context
->
generate_id
();
connection_id
=
_srs_context
->
get_id
();
ret
=
do_cycle
();
// if socket io error, set to closed.
if
(
srs_is_client_gracefully_close
(
ret
))
{
ret
=
ERROR_SOCKET_CLOSED
;
}
// success.
if
(
ret
==
ERROR_SUCCESS
)
{
srs_trace
(
"client process normally finished. ret=%d"
,
ret
);
}
// client close peer.
if
(
ret
==
ERROR_SOCKET_CLOSED
)
{
srs_warn
(
"client disconnect peer. ret=%d"
,
ret
);
}
server
->
remove
(
this
);
}
void
*
SrsConnection
::
cycle_thread
(
void
*
arg
)
{
SrsConnection
*
conn
=
(
SrsConnection
*
)
arg
;
srs_assert
(
conn
!=
NULL
);
conn
->
cycle
();
return
NULL
;
}
...
...
trunk/src/app/srs_app_conn.hpp
查看文件 @
96a5c7b
...
...
@@ -31,10 +31,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#include <srs_app_st.hpp>
#include <srs_app_thread.hpp>
class
SrsServer
;
class
SrsConnection
class
SrsConnection
:
public
ISrsThreadHandler
{
private
:
SrsThread
*
pthread
;
protected
:
char
*
ip
;
SrsServer
*
server
;
...
...
@@ -45,13 +48,13 @@ public:
virtual
~
SrsConnection
();
public
:
virtual
int
start
();
virtual
int
cycle
();
virtual
void
on_thread_stop
();
protected
:
virtual
int
do_cycle
()
=
0
;
virtual
void
stop
();
protected
:
virtual
int
get_peer_ip
();
private
:
virtual
void
cycle
();
static
void
*
cycle_thread
(
void
*
arg
);
};
#endif
\ No newline at end of file
...
...
trunk/src/app/srs_app_edge.cpp
查看文件 @
96a5c7b
...
...
@@ -335,6 +335,9 @@ SrsEdgeForwarder::SrsEdgeForwarder()
SrsEdgeForwarder
::~
SrsEdgeForwarder
()
{
stop
();
srs_freep
(
pthread
);
srs_freep
(
queue
);
}
void
SrsEdgeForwarder
::
set_queue_size
(
double
queue_size
)
...
...
trunk/src/app/srs_app_encoder.cpp
查看文件 @
96a5c7b
...
...
@@ -53,6 +53,7 @@ SrsEncoder::~SrsEncoder()
on_unpublish
();
srs_freep
(
pthread
);
srs_freep
(
pithy_print
);
}
int
SrsEncoder
::
on_publish
(
SrsRequest
*
req
)
...
...
trunk/src/app/srs_app_rtmp_conn.cpp
查看文件 @
96a5c7b
...
...
@@ -79,6 +79,8 @@ SrsRtmpConn::~SrsRtmpConn()
{
_srs_config
->
unsubscribe
(
this
);
stop
();
srs_freep
(
req
);
srs_freep
(
res
);
srs_freep
(
rtmp
);
...
...
trunk/src/app/srs_app_server.cpp
查看文件 @
96a5c7b
...
...
@@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef SRS_AUTO_INGEST
#include <srs_app_ingest.hpp>
#endif
#include <srs_app_source.hpp>
#define SERVER_LISTEN_BACKLOG 512
...
...
@@ -251,6 +252,13 @@ int SrsSignalManager::start()
sa
.
sa_flags
=
0
;
sigaction
(
SIGINT
,
&
sa
,
NULL
);
sa
.
sa_handler
=
SrsSignalManager
::
sig_catcher
;
sigemptyset
(
&
sa
.
sa_mask
);
sa
.
sa_flags
=
0
;
sigaction
(
SIGUSR2
,
&
sa
,
NULL
);
srs_trace
(
"signal installed"
);
return
pthread
->
start
();
}
...
...
@@ -316,27 +324,17 @@ SrsServer::~SrsServer()
void
SrsServer
::
destroy
()
{
_srs_config
->
unsubscribe
(
this
);
srs_warn
(
"start destroy server"
);
if
(
true
)
{
std
::
vector
<
SrsConnection
*>::
iterator
it
;
for
(
it
=
conns
.
begin
();
it
!=
conns
.
end
();
++
it
)
{
SrsConnection
*
conn
=
*
it
;
srs_freep
(
conn
);
}
conns
.
clear
();
}
_srs_config
->
unsubscribe
(
this
);
close_listeners
(
SrsListenerRtmpStream
);
close_listeners
(
SrsListenerHttpApi
);
close_listeners
(
SrsListenerHttpStream
);
if
(
pid_fd
>
0
)
{
::
close
(
pid_fd
);
pid_fd
=
-
1
;
}
srs_freep
(
signal_manager
);
#ifdef SRS_AUTO_INGEST
ingester
->
stop
();
#endif
#ifdef SRS_AUTO_HTTP_API
srs_freep
(
http_api_handler
);
...
...
@@ -348,6 +346,27 @@ void SrsServer::destroy()
#ifdef SRS_AUTO_INGEST
srs_freep
(
ingester
);
#endif
if
(
pid_fd
>
0
)
{
::
close
(
pid_fd
);
pid_fd
=
-
1
;
}
srs_freep
(
signal_manager
);
for
(
std
::
vector
<
SrsConnection
*>::
iterator
it
=
conns
.
begin
();
it
!=
conns
.
end
();)
{
SrsConnection
*
conn
=
*
it
;
// remove the connection, then free it,
// for the free will remove itself from server,
// when erased here, the remove of server will ignore.
it
=
conns
.
erase
(
it
);
srs_freep
(
conn
);
}
conns
.
clear
();
SrsSource
::
destroy
();
}
int
SrsServer
::
initialize
()
...
...
@@ -540,12 +559,14 @@ int SrsServer::cycle()
ret
=
do_cycle
();
#ifdef SRS_AUTO_INGEST
ingester
->
stop
();
#endif
destroy
();
#ifdef SRS_AUTO_GPERF_MC
srs_warn
(
"sleep a long time for system st-threads to cleanup."
);
st_usleep
(
3
*
1000
*
1000
);
srs_warn
(
"system quit"
);
#endif
return
ret
;
}
...
...
@@ -553,10 +574,14 @@ void SrsServer::remove(SrsConnection* conn)
{
std
::
vector
<
SrsConnection
*>::
iterator
it
=
std
::
find
(
conns
.
begin
(),
conns
.
end
(),
conn
);
if
(
it
!=
conns
.
end
())
{
conns
.
erase
(
it
);
// removed by destroy, ignore.
if
(
it
==
conns
.
end
())
{
srs_warn
(
"server moved connection, ignore."
);
return
;
}
conns
.
erase
(
it
);
srs_info
(
"conn removed. conns=%d"
,
(
int
)
conns
.
size
());
// all connections are created by server,
...
...
@@ -571,7 +596,7 @@ void SrsServer::on_signal(int signo)
return
;
}
if
(
signo
==
SIGINT
)
{
if
(
signo
==
SIGINT
||
signo
==
SIGUSR2
)
{
#ifdef SRS_AUTO_GPERF_MC
srs_trace
(
"gmc is on, main cycle will terminate normally."
);
signal_gmc_stop
=
true
;
...
...
@@ -611,6 +636,7 @@ int SrsServer::do_cycle()
// because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
if
(
signal_gmc_stop
)
{
srs_warn
(
"gmc got singal to stop server."
);
return
ret
;
}
#endif
...
...
trunk/src/app/srs_app_source.cpp
查看文件 @
96a5c7b
...
...
@@ -437,6 +437,16 @@ int SrsSource::find(SrsRequest* req, SrsSource** ppsource)
return
ret
;
}
void
SrsSource
::
destroy
()
{
std
::
map
<
std
::
string
,
SrsSource
*>::
iterator
it
;
for
(
it
=
pool
.
begin
();
it
!=
pool
.
end
();
++
it
)
{
SrsSource
*
source
=
it
->
second
;
srs_freep
(
source
);
}
pool
.
clear
();
}
SrsSource
::
SrsSource
(
SrsRequest
*
req
)
{
_req
=
req
->
copy
();
...
...
@@ -468,14 +478,9 @@ SrsSource::~SrsSource()
{
_srs_config
->
unsubscribe
(
this
);
if
(
true
)
{
std
::
vector
<
SrsConsumer
*>::
iterator
it
;
for
(
it
=
consumers
.
begin
();
it
!=
consumers
.
end
();
++
it
)
{
SrsConsumer
*
consumer
=
*
it
;
srs_freep
(
consumer
);
}
consumers
.
clear
();
}
// never free the consumers,
// for all consumers are auto free.
consumers
.
clear
();
if
(
true
)
{
std
::
vector
<
SrsForwarder
*>::
iterator
it
;
...
...
trunk/src/app/srs_app_source.hpp
查看文件 @
96a5c7b
...
...
@@ -222,6 +222,11 @@ public:
* @remark stream_url should without port and schema.
*/
static
int
find
(
SrsRequest
*
req
,
SrsSource
**
ppsource
);
/**
* when system exit, destroy the sources,
* for gmc to analysis mem leaks.
*/
static
void
destroy
();
private
:
// deep copy of client request.
SrsRequest
*
_req
;
...
...
trunk/src/app/srs_app_thread.cpp
查看文件 @
96a5c7b
...
...
@@ -121,6 +121,11 @@ bool SrsThread::can_loop()
return
loop
;
}
void
SrsThread
::
stop_loop
()
{
loop
=
false
;
}
void
SrsThread
::
thread_cycle
()
{
int
ret
=
ERROR_SUCCESS
;
...
...
trunk/src/app/srs_app_thread.hpp
查看文件 @
96a5c7b
...
...
@@ -49,19 +49,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* when thread interrupt, the socket maybe not got EINT,
* espectially on st_usleep(), so the cycle must check the loop,
* when handler->cycle() has loop itself, for example:
* handler->cycle() is:
* while (true):
* st_usleep(0);
* if (read_from_socket(skt) < 0) break;
* while (true):
* st_usleep(0);
* if (read_from_socket(skt) < 0) break;
* if thread stop when read_from_socket, it's ok, the loop will break,
* but when thread stop interrupt the s_usleep(0), then the loop is
* death loop.
* in a word, the handler->cycle() must:
* handler->cycle() is:
* while (pthread->can_loop()):
* st_usleep(0);
* if (read_from_socket(skt) < 0) break;
* while (pthread->can_loop()):
* st_usleep(0);
* if (read_from_socket(skt) < 0) break;
* check the loop, then it works.
*
* in the thread itself, that is the cycle method,
* if itself want to terminate the thread, should never use stop(),
* but use stop_loop() to set the loop to false and terminate normally.
*/
class
ISrsThreadHandler
{
...
...
@@ -117,12 +119,19 @@ public:
* @remark user can stop multiple times, ignore if already stopped.
*/
virtual
void
stop
();
public
:
/**
* whether the thread should loop,
* used for handler->cycle() which has a loop method,
* to check this method, break if false.
*/
virtual
bool
can_loop
();
/**
* for the loop thread to stop the loop.
* other thread can directly use stop() to stop loop and wait for quit.
* this stop loop method only set loop to false.
*/
virtual
void
stop_loop
();
private
:
virtual
void
thread_cycle
();
static
void
*
thread_fun
(
void
*
arg
);
...
...
trunk/src/core/srs_core.hpp
查看文件 @
96a5c7b
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "8
8
"
#define VERSION_REVISION "8
9
"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "srs"
...
...
请
注册
或
登录
后发表评论