mirror of
https://github.com/ossrs/srs.git
synced 2025-02-12 11:21:52 +00:00
support reload config(listen and chunk_size) by SIGHUP(1).
This commit is contained in:
parent
cc44329f37
commit
68ccd7eb64
13 changed files with 366 additions and 72 deletions
|
@ -48,6 +48,7 @@ url: rtmp://127.0.0.1:1935/live/livestream
|
||||||
* nginx v1.5.0: 139524 lines <br/>
|
* nginx v1.5.0: 139524 lines <br/>
|
||||||
|
|
||||||
### History
|
### History
|
||||||
|
* v0.4, 2013-11-09, support reload config(listen and chunk_size) by SIGHUP(1).
|
||||||
* v0.4, 2013-11-09, support longtime(>4.6hours) publish/play.
|
* v0.4, 2013-11-09, support longtime(>4.6hours) publish/play.
|
||||||
* v0.4, 2013-11-09, support config the chunk_size.
|
* v0.4, 2013-11-09, support config the chunk_size.
|
||||||
* v0.4, 2013-11-09, support pause for live stream.
|
* v0.4, 2013-11-09, support pause for live stream.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# the listen ports, split by space.
|
# the listen ports, split by space.
|
||||||
listen 1935 19350;
|
listen 1935;
|
||||||
# the default chunk size is 128, max is 65536,
|
# the default chunk size is 128, max is 65536,
|
||||||
# some client does not support chunk size change,
|
# some client does not support chunk size change,
|
||||||
# however, most clients supports it and it can improve
|
# however, most clients supports it and it can improve
|
||||||
|
|
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -91,7 +91,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
|
||||||
"srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
|
"srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
|
||||||
"srs_core_stream" "srs_core_source" "srs_core_codec"
|
"srs_core_stream" "srs_core_source" "srs_core_codec"
|
||||||
"srs_core_complex_handshake" "srs_core_pithy_print"
|
"srs_core_complex_handshake" "srs_core_pithy_print"
|
||||||
"srs_core_config" "srs_core_refer")
|
"srs_core_config" "srs_core_refer" "srs_core_reload")
|
||||||
MODULE_DIR="src/core" . auto/modules.sh
|
MODULE_DIR="src/core" . auto/modules.sh
|
||||||
CORE_OBJS="${MODULE_OBJS[@]}"
|
CORE_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
|
||||||
|
|
|
@ -84,4 +84,7 @@ extern int64_t srs_get_system_time_ms();
|
||||||
// the deamon st-thread will update it.
|
// the deamon st-thread will update it.
|
||||||
extern void srs_update_system_time_ms();
|
extern void srs_update_system_time_ms();
|
||||||
|
|
||||||
|
// signal defines.
|
||||||
|
#define SIGNAL_RELOAD SIGHUP
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -34,8 +34,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <srs_core_error.hpp>
|
#include <srs_core_error.hpp>
|
||||||
|
#include <srs_core_log.hpp>
|
||||||
|
#include <srs_core_auto_free.hpp>
|
||||||
|
|
||||||
#define FILE_OFFSET(fd) lseek(fd, 0, SEEK_CUR)
|
#define FILE_OFFSET(fd) lseek(fd, 0, SEEK_CUR)
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ int SrsFileBuffer::open(const char* filename)
|
||||||
assert(fd == -1);
|
assert(fd == -1);
|
||||||
|
|
||||||
if ((fd = ::open(filename, O_RDONLY, 0)) < 0) {
|
if ((fd = ::open(filename, O_RDONLY, 0)) < 0) {
|
||||||
fprintf(stderr, "open conf file error. errno=%d(%s)\n", errno, strerror(errno));
|
srs_error("open conf file error. errno=%d(%s)", errno, strerror(errno));
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,21 +185,21 @@ int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type)
|
||||||
}
|
}
|
||||||
if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
|
if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
|
||||||
if (type != parse_block) {
|
if (type != parse_block) {
|
||||||
fprintf(stderr, "line %d: unexpected \"}\"\n", buffer->line);
|
srs_error("line %d: unexpected \"}\"", buffer->line);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
if (ret == ERROR_SYSTEM_CONFIG_EOF) {
|
if (ret == ERROR_SYSTEM_CONFIG_EOF) {
|
||||||
if (type == parse_block) {
|
if (type == parse_block) {
|
||||||
fprintf(stderr, "line %d: unexpected end of file, expecting \"}\"\n", buffer->line);
|
srs_error("line %d: unexpected end of file, expecting \"}\"", buffer->line);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
fprintf(stderr, "line %d: empty directive.\n", buffer->line);
|
srs_error("line %d: empty directive.", buffer->line);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +242,7 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
|
||||||
while (true) {
|
while (true) {
|
||||||
if ((ret = refill_buffer(buffer, d_quoted, s_quoted, startline, pstart)) != ERROR_SUCCESS) {
|
if ((ret = refill_buffer(buffer, d_quoted, s_quoted, startline, pstart)) != ERROR_SUCCESS) {
|
||||||
if (!args.empty() || !last_space) {
|
if (!args.empty() || !last_space) {
|
||||||
fprintf(stderr, "line %d: unexpected end of file, expecting ; or \"}\"\n", buffer->line);
|
srs_error("line %d: unexpected end of file, expecting ; or \"}\"", buffer->line);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -268,7 +271,7 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
|
||||||
if (ch == '{') {
|
if (ch == '{') {
|
||||||
return ERROR_SYSTEM_CONFIG_BLOCK_START;
|
return ERROR_SYSTEM_CONFIG_BLOCK_START;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "line %d: unexpected '%c'\n", buffer->line, ch);
|
srs_error("line %d: unexpected '%c'", buffer->line, ch);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,19 +285,19 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ';':
|
case ';':
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
fprintf(stderr, "line %d: unexpected ';'\n", buffer->line);
|
srs_error("line %d: unexpected ';'", buffer->line);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
return ERROR_SYSTEM_CONFIG_DIRECTIVE;
|
return ERROR_SYSTEM_CONFIG_DIRECTIVE;
|
||||||
case '{':
|
case '{':
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
fprintf(stderr, "line %d: unexpected '{'\n", buffer->line);
|
srs_error("line %d: unexpected '{'", buffer->line);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
return ERROR_SYSTEM_CONFIG_BLOCK_START;
|
return ERROR_SYSTEM_CONFIG_BLOCK_START;
|
||||||
case '}':
|
case '}':
|
||||||
if (args.size() != 0) {
|
if (args.size() != 0) {
|
||||||
fprintf(stderr, "line %d: unexpected '}'\n", buffer->line);
|
srs_error("line %d: unexpected '}'", buffer->line);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
return ERROR_SYSTEM_CONFIG_BLOCK_END;
|
return ERROR_SYSTEM_CONFIG_BLOCK_END;
|
||||||
|
@ -376,12 +379,12 @@ int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s
|
||||||
buffer->line = startline;
|
buffer->line = startline;
|
||||||
|
|
||||||
if (!d_quoted && !s_quoted) {
|
if (!d_quoted && !s_quoted) {
|
||||||
fprintf(stderr, "line %d: too long parameter \"%*s...\" started\n",
|
srs_error("line %d: too long parameter \"%*s...\" started",
|
||||||
buffer->line, 10, buffer->start);
|
buffer->line, 10, buffer->start);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "line %d: too long parameter, "
|
srs_error("line %d: too long parameter, "
|
||||||
"probably missing terminating '%c' character\n", buffer->line, d_quoted? '"':'\'');
|
"probably missing terminating '%c' character", buffer->line, d_quoted? '"':'\'');
|
||||||
}
|
}
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +396,7 @@ int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s
|
||||||
size = srs_min(size, buffer->end - (buffer->start + len));
|
size = srs_min(size, buffer->end - (buffer->start + len));
|
||||||
int n = read(buffer->fd, buffer->start + len, size);
|
int n = read(buffer->fd, buffer->start + len, size);
|
||||||
if (n != size) {
|
if (n != size) {
|
||||||
fprintf(stderr, "read file read error. expect %d, actual %d bytes.\n", size, n);
|
srs_error("read file read error. expect %d, actual %d bytes.", size, n);
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,26 +407,85 @@ int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* config = new Config();
|
SrsConfig* config = new SrsConfig();
|
||||||
|
|
||||||
Config::Config()
|
SrsConfig::SrsConfig()
|
||||||
{
|
{
|
||||||
show_help = false;
|
show_help = false;
|
||||||
show_version = false;
|
show_version = false;
|
||||||
config_file = NULL;
|
|
||||||
|
|
||||||
root = new SrsConfDirective();
|
root = new SrsConfDirective();
|
||||||
root->conf_line = 0;
|
root->conf_line = 0;
|
||||||
root->name = "root";
|
root->name = "root";
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::~Config()
|
SrsConfig::~SrsConfig()
|
||||||
{
|
{
|
||||||
srs_freep(root);
|
srs_freep(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsConfig::reload()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsConfig conf;
|
||||||
|
if ((ret = conf.parse_file(config_file.c_str())) != ERROR_SUCCESS) {
|
||||||
|
srs_error("config reloader parse file failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_info("config reloader parse file success.");
|
||||||
|
|
||||||
|
// store current root to old_root,
|
||||||
|
// and reap the root from conf to current root.
|
||||||
|
SrsConfDirective* old_root = root;
|
||||||
|
SrsAutoFree(SrsConfDirective, old_root, false);
|
||||||
|
|
||||||
|
root = conf.root;
|
||||||
|
conf.root = NULL;
|
||||||
|
|
||||||
|
// merge config.
|
||||||
|
std::vector<SrsReloadHandler*>::iterator it;
|
||||||
|
|
||||||
|
// merge config: listen
|
||||||
|
if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) {
|
||||||
|
for (it = subscribes.begin(); it != subscribes.end(); ++it) {
|
||||||
|
SrsReloadHandler* subscribe = *it;
|
||||||
|
if ((ret = subscribe->on_reload_listen()) != ERROR_SUCCESS) {
|
||||||
|
srs_error("notify subscribes reload listen failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsConfig::subscribe(SrsReloadHandler* handler)
|
||||||
|
{
|
||||||
|
std::vector<SrsReloadHandler*>::iterator it;
|
||||||
|
|
||||||
|
it = std::find(subscribes.begin(), subscribes.end(), handler);
|
||||||
|
if (it != subscribes.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribes.push_back(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsConfig::unsubscribe(SrsReloadHandler* handler)
|
||||||
|
{
|
||||||
|
std::vector<SrsReloadHandler*>::iterator it;
|
||||||
|
|
||||||
|
it = std::find(subscribes.begin(), subscribes.end(), handler);
|
||||||
|
if (it == subscribes.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribes.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
// see: ngx_get_options
|
// see: ngx_get_options
|
||||||
int Config::parse_options(int argc, char** argv)
|
int SrsConfig::parse_options(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -438,33 +500,23 @@ int Config::parse_options(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_version) {
|
if (show_version) {
|
||||||
fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);
|
printf("%s\n", RTMP_SIG_SRS_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_help || show_version) {
|
if (show_help || show_version) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config_file) {
|
if (config_file.empty()) {
|
||||||
fprintf(stderr, "config file not specified, see help: %s -h\n", argv[0]);
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret);
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = root->parse(config_file)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* conf = NULL;
|
return parse_file(config_file.c_str());
|
||||||
if ((conf = get_listen()) == NULL || conf->args.size() == 0) {
|
|
||||||
fprintf(stderr, "line %d: conf error, "
|
|
||||||
"directive \"listen\" is empty\n", conf? conf->conf_line:0);
|
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_vhost(std::string vhost)
|
SrsConfDirective* SrsConfig::get_vhost(std::string vhost)
|
||||||
{
|
{
|
||||||
srs_assert(root);
|
srs_assert(root);
|
||||||
|
|
||||||
|
@ -487,7 +539,7 @@ SrsConfDirective* Config::get_vhost(std::string vhost)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_gop_cache(std::string vhost)
|
SrsConfDirective* SrsConfig::get_gop_cache(std::string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
@ -498,7 +550,7 @@ SrsConfDirective* Config::get_gop_cache(std::string vhost)
|
||||||
return conf->get("gop_cache");
|
return conf->get("gop_cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_refer(std::string vhost)
|
SrsConfDirective* SrsConfig::get_refer(std::string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
@ -509,7 +561,7 @@ SrsConfDirective* Config::get_refer(std::string vhost)
|
||||||
return conf->get("refer");
|
return conf->get("refer");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_refer_play(std::string vhost)
|
SrsConfDirective* SrsConfig::get_refer_play(std::string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
@ -520,7 +572,7 @@ SrsConfDirective* Config::get_refer_play(std::string vhost)
|
||||||
return conf->get("refer_play");
|
return conf->get("refer_play");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_refer_publish(std::string vhost)
|
SrsConfDirective* SrsConfig::get_refer_publish(std::string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
@ -531,26 +583,52 @@ SrsConfDirective* Config::get_refer_publish(std::string vhost)
|
||||||
return conf->get("refer_publish");
|
return conf->get("refer_publish");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_listen()
|
SrsConfDirective* SrsConfig::get_listen()
|
||||||
{
|
{
|
||||||
return root->get("listen");
|
return root->get("listen");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* Config::get_chunk_size()
|
SrsConfDirective* SrsConfig::get_chunk_size()
|
||||||
{
|
{
|
||||||
return root->get("chunk_size");
|
return root->get("chunk_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Config::parse_argv(int& i, char** argv)
|
int SrsConfig::parse_file(const char* filename)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
config_file = filename;
|
||||||
|
|
||||||
|
if (config_file.empty()) {
|
||||||
|
return ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = root->parse(config_file.c_str())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsConfDirective* conf = NULL;
|
||||||
|
if ((conf = get_listen()) == NULL || conf->args.size() == 0) {
|
||||||
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
|
srs_error("line %d: conf error, "
|
||||||
|
"directive \"listen\" is empty, ret=%d", (conf? conf->conf_line:0), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsConfig::parse_argv(int& i, char** argv)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
char* p = argv[i];
|
char* p = argv[i];
|
||||||
|
|
||||||
if (*p++ != '-') {
|
if (*p++ != '-') {
|
||||||
fprintf(stderr, "invalid options(index=%d, value=%s), "
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
"must starts with -, see help: %s -h\n", i, argv[i], argv[0]);
|
srs_error("invalid options(index=%d, value=%s), "
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
"must starts with -, see help: %s -h, ret=%d", i, argv[i], argv[0], ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
|
@ -572,20 +650,22 @@ int Config::parse_argv(int& i, char** argv)
|
||||||
config_file = argv[i];
|
config_file = argv[i];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "option \"-c\" requires parameter\n");
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
srs_error("option \"-c\" requires parameter, ret=%d", ret);
|
||||||
|
return ret;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "invalid option: \"%c\", see help: %s -h\n", *(p - 1), argv[0]);
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
return ERROR_SYSTEM_CONFIG_INVALID;
|
srs_error("invalid option: \"%c\", see help: %s -h, ret=%d", *(p - 1), argv[0], ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::print_help(char** argv)
|
void SrsConfig::print_help(char** argv)
|
||||||
{
|
{
|
||||||
fprintf(stderr, RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION
|
printf(RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION
|
||||||
" Copyright (c) 2013 winlin\n"
|
" Copyright (c) 2013 winlin\n"
|
||||||
"Usage: %s [-h?vV] [-c <filename>]\n"
|
"Usage: %s [-h?vV] [-c <filename>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -600,3 +680,39 @@ void Config::print_help(char** argv)
|
||||||
argv[0]);
|
argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
|
||||||
|
{
|
||||||
|
if (!a || !b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->name != b->name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->args.size() != b->args.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)a->args.size(); i++) {
|
||||||
|
if (a->args.at(i) != b->args.at(i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->directives.size() != b->directives.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)a->directives.size(); i++) {
|
||||||
|
SrsConfDirective* a0 = a->at(i);
|
||||||
|
SrsConfDirective* b0 = b->at(i);
|
||||||
|
|
||||||
|
if (!srs_directive_equals(a0, b0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <srs_core_reload.hpp>
|
||||||
|
|
||||||
// default vhost for rtmp
|
// default vhost for rtmp
|
||||||
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
|
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
|
||||||
|
|
||||||
|
@ -84,16 +86,21 @@ public:
|
||||||
/**
|
/**
|
||||||
* the config parser.
|
* the config parser.
|
||||||
*/
|
*/
|
||||||
class Config
|
class SrsConfig
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool show_help;
|
bool show_help;
|
||||||
bool show_version;
|
bool show_version;
|
||||||
char* config_file;
|
std::string config_file;
|
||||||
SrsConfDirective* root;
|
SrsConfDirective* root;
|
||||||
|
std::vector<SrsReloadHandler*> subscribes;
|
||||||
public:
|
public:
|
||||||
Config();
|
SrsConfig();
|
||||||
virtual ~Config();
|
virtual ~SrsConfig();
|
||||||
|
public:
|
||||||
|
virtual int reload();
|
||||||
|
virtual void subscribe(SrsReloadHandler* handler);
|
||||||
|
virtual void unsubscribe(SrsReloadHandler* handler);
|
||||||
public:
|
public:
|
||||||
virtual int parse_options(int argc, char** argv);
|
virtual int parse_options(int argc, char** argv);
|
||||||
virtual SrsConfDirective* get_vhost(std::string vhost);
|
virtual SrsConfDirective* get_vhost(std::string vhost);
|
||||||
|
@ -104,11 +111,17 @@ public:
|
||||||
virtual SrsConfDirective* get_listen();
|
virtual SrsConfDirective* get_listen();
|
||||||
virtual SrsConfDirective* get_chunk_size();
|
virtual SrsConfDirective* get_chunk_size();
|
||||||
private:
|
private:
|
||||||
|
virtual int parse_file(const char* filename);
|
||||||
virtual int parse_argv(int& i, char** argv);
|
virtual int parse_argv(int& i, char** argv);
|
||||||
virtual void print_help(char** argv);
|
virtual void print_help(char** argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deep compare directive.
|
||||||
|
*/
|
||||||
|
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b);
|
||||||
|
|
||||||
// global config
|
// global config
|
||||||
extern Config* config;
|
extern SrsConfig* config;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -36,8 +36,13 @@ SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
|
||||||
SrsConnection::~SrsConnection()
|
SrsConnection::~SrsConnection()
|
||||||
{
|
{
|
||||||
if (stfd) {
|
if (stfd) {
|
||||||
|
int fd = st_netfd_fileno(stfd);
|
||||||
st_netfd_close(stfd);
|
st_netfd_close(stfd);
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
|
|
||||||
|
// st does not close it sometimes,
|
||||||
|
// close it manually.
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
trunk/src/core/srs_core_reload.cpp
Executable file
41
trunk/src/core/srs_core_reload.cpp
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <srs_core_reload.hpp>
|
||||||
|
|
||||||
|
#include <srs_core_error.hpp>
|
||||||
|
|
||||||
|
SrsReloadHandler::SrsReloadHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsReloadHandler::~SrsReloadHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsReloadHandler::on_reload_listen()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
44
trunk/src/core/srs_core_reload.hpp
Executable file
44
trunk/src/core/srs_core_reload.hpp
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRS_CORE_RELOAD_HPP
|
||||||
|
#define SRS_CORE_RELOAD_HPP
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <srs_core_reload.hpp>
|
||||||
|
*/
|
||||||
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the handler for config reload.
|
||||||
|
*/
|
||||||
|
class SrsReloadHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsReloadHandler();
|
||||||
|
virtual ~SrsReloadHandler();
|
||||||
|
public:
|
||||||
|
virtual int on_reload_listen();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core_config.hpp>
|
#include <srs_core_config.hpp>
|
||||||
|
|
||||||
#define SERVER_LISTEN_BACKLOG 10
|
#define SERVER_LISTEN_BACKLOG 10
|
||||||
#define SRS_TIME_RESOLUTION_MS 1000
|
#define SRS_TIME_RESOLUTION_MS 500
|
||||||
|
|
||||||
SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
|
SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,9 @@ SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
|
||||||
port = 0;
|
port = 0;
|
||||||
server = _server;
|
server = _server;
|
||||||
type = _type;
|
type = _type;
|
||||||
|
|
||||||
|
tid = NULL;
|
||||||
|
loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsListener::~SrsListener()
|
SrsListener::~SrsListener()
|
||||||
|
@ -55,6 +59,17 @@ SrsListener::~SrsListener()
|
||||||
st_netfd_close(stfd);
|
st_netfd_close(stfd);
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tid) {
|
||||||
|
loop = false;
|
||||||
|
st_thread_interrupt(tid);
|
||||||
|
st_thread_join(tid, NULL);
|
||||||
|
tid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// st does not close it sometimes,
|
||||||
|
// close it manually.
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsListener::listen(int _port)
|
int SrsListener::listen(int _port)
|
||||||
|
@ -103,7 +118,7 @@ int SrsListener::listen(int _port)
|
||||||
}
|
}
|
||||||
srs_verbose("st open socket success. fd=%d", fd);
|
srs_verbose("st open socket success. fd=%d", fd);
|
||||||
|
|
||||||
if (st_thread_create(listen_thread, this, 0, 0) == NULL) {
|
if ((tid = st_thread_create(listen_thread, this, 1, 0)) == NULL) {
|
||||||
ret = ERROR_ST_CREATE_LISTEN_THREAD;
|
ret = ERROR_ST_CREATE_LISTEN_THREAD;
|
||||||
srs_error("st_thread_create listen thread error. ret=%d", ret);
|
srs_error("st_thread_create listen thread error. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -122,7 +137,7 @@ void SrsListener::listen_cycle()
|
||||||
log_context->generate_id();
|
log_context->generate_id();
|
||||||
srs_trace("listen cycle start, port=%d, type=%d, fd=%d", port, type, fd);
|
srs_trace("listen cycle start, port=%d, type=%d, fd=%d", port, type, fd);
|
||||||
|
|
||||||
while (true) {
|
while (loop) {
|
||||||
st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
|
st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
|
||||||
|
|
||||||
if(client_stfd == NULL){
|
if(client_stfd == NULL){
|
||||||
|
@ -146,6 +161,7 @@ void* SrsListener::listen_thread(void* arg)
|
||||||
SrsListener* obj = (SrsListener*)arg;
|
SrsListener* obj = (SrsListener*)arg;
|
||||||
srs_assert(obj != NULL);
|
srs_assert(obj != NULL);
|
||||||
|
|
||||||
|
obj->loop = true;
|
||||||
obj->listen_cycle();
|
obj->listen_cycle();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -153,10 +169,15 @@ void* SrsListener::listen_thread(void* arg)
|
||||||
|
|
||||||
SrsServer::SrsServer()
|
SrsServer::SrsServer()
|
||||||
{
|
{
|
||||||
|
signal_reload = false;
|
||||||
|
|
||||||
|
config->subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsServer::~SrsServer()
|
SrsServer::~SrsServer()
|
||||||
{
|
{
|
||||||
|
config->unsubscribe(this);
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
std::vector<SrsConnection*>::iterator it;
|
std::vector<SrsConnection*>::iterator it;
|
||||||
for (it = conns.begin(); it != conns.end(); ++it) {
|
for (it = conns.begin(); it != conns.end(); ++it) {
|
||||||
|
@ -166,14 +187,7 @@ SrsServer::~SrsServer()
|
||||||
conns.clear();
|
conns.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
close_listeners();
|
||||||
std::vector<SrsListener*>::iterator it;
|
|
||||||
for (it = listeners.begin(); it != listeners.end(); ++it) {
|
|
||||||
SrsListener* listener = *it;
|
|
||||||
srs_freep(listener);
|
|
||||||
}
|
|
||||||
listeners.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsServer::initialize()
|
int SrsServer::initialize()
|
||||||
|
@ -212,6 +226,8 @@ int SrsServer::listen()
|
||||||
conf = config->get_listen();
|
conf = config->get_listen();
|
||||||
srs_assert(conf);
|
srs_assert(conf);
|
||||||
|
|
||||||
|
close_listeners();
|
||||||
|
|
||||||
for (int i = 0; i < (int)conf->args.size(); i++) {
|
for (int i = 0; i < (int)conf->args.size(); i++) {
|
||||||
SrsListener* listener = new SrsListener(this, SrsListenerStream);
|
SrsListener* listener = new SrsListener(this, SrsListenerStream);
|
||||||
listeners.push_back(listener);
|
listeners.push_back(listener);
|
||||||
|
@ -234,6 +250,17 @@ int SrsServer::cycle()
|
||||||
while (true) {
|
while (true) {
|
||||||
st_usleep(SRS_TIME_RESOLUTION_MS * 1000);
|
st_usleep(SRS_TIME_RESOLUTION_MS * 1000);
|
||||||
srs_update_system_time_ms();
|
srs_update_system_time_ms();
|
||||||
|
|
||||||
|
if (signal_reload) {
|
||||||
|
signal_reload = false;
|
||||||
|
srs_info("get signal reload, to reload the config.");
|
||||||
|
|
||||||
|
if ((ret = config->reload()) != ERROR_SUCCESS) {
|
||||||
|
srs_error("reload config failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_trace("reload config success.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -254,6 +281,23 @@ void SrsServer::remove(SrsConnection* conn)
|
||||||
srs_freep(conn);
|
srs_freep(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsServer::on_signal(int signo)
|
||||||
|
{
|
||||||
|
if (signo == SIGNAL_RELOAD) {
|
||||||
|
signal_reload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsServer::close_listeners()
|
||||||
|
{
|
||||||
|
std::vector<SrsListener*>::iterator it;
|
||||||
|
for (it = listeners.begin(); it != listeners.end(); ++it) {
|
||||||
|
SrsListener* listener = *it;
|
||||||
|
srs_freep(listener);
|
||||||
|
}
|
||||||
|
listeners.clear();
|
||||||
|
}
|
||||||
|
|
||||||
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -279,3 +323,10 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsServer::on_reload_listen()
|
||||||
|
{
|
||||||
|
return listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsServer server;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include <st.h>
|
#include <st.h>
|
||||||
|
|
||||||
|
#include <srs_core_reload.hpp>
|
||||||
|
|
||||||
class SrsServer;
|
class SrsServer;
|
||||||
class SrsConnection;
|
class SrsConnection;
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ private:
|
||||||
st_netfd_t stfd;
|
st_netfd_t stfd;
|
||||||
int port;
|
int port;
|
||||||
SrsServer* server;
|
SrsServer* server;
|
||||||
|
st_thread_t tid;
|
||||||
|
bool loop;
|
||||||
public:
|
public:
|
||||||
SrsListener(SrsServer* _server, SrsListenerType _type);
|
SrsListener(SrsServer* _server, SrsListenerType _type);
|
||||||
virtual ~SrsListener();
|
virtual ~SrsListener();
|
||||||
|
@ -62,12 +66,13 @@ private:
|
||||||
static void* listen_thread(void* arg);
|
static void* listen_thread(void* arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsServer
|
class SrsServer : public SrsReloadHandler
|
||||||
{
|
{
|
||||||
friend class SrsListener;
|
friend class SrsListener;
|
||||||
private:
|
private:
|
||||||
std::vector<SrsConnection*> conns;
|
std::vector<SrsConnection*> conns;
|
||||||
std::vector<SrsListener*> listeners;
|
std::vector<SrsListener*> listeners;
|
||||||
|
bool signal_reload;
|
||||||
public:
|
public:
|
||||||
SrsServer();
|
SrsServer();
|
||||||
virtual ~SrsServer();
|
virtual ~SrsServer();
|
||||||
|
@ -76,8 +81,14 @@ public:
|
||||||
virtual int listen();
|
virtual int listen();
|
||||||
virtual int cycle();
|
virtual int cycle();
|
||||||
virtual void remove(SrsConnection* conn);
|
virtual void remove(SrsConnection* conn);
|
||||||
|
virtual void on_signal(int signo);
|
||||||
private:
|
private:
|
||||||
|
virtual void close_listeners();
|
||||||
virtual int accept_client(SrsListenerType type, st_netfd_t client_stfd);
|
virtual int accept_client(SrsListenerType type, st_netfd_t client_stfd);
|
||||||
|
public:
|
||||||
|
virtual int on_reload_listen();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern SrsServer server;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -27,16 +27,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core_config.hpp>
|
#include <srs_core_config.hpp>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
void handler(int signo)
|
||||||
|
{
|
||||||
|
srs_trace("get a signal, signo=%d", signo);
|
||||||
|
server.on_signal(signo);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
signal(SIGNAL_RELOAD, handler);
|
||||||
|
|
||||||
if ((ret = config->parse_options(argc, argv)) != ERROR_SUCCESS) {
|
if ((ret = config->parse_options(argc, argv)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsServer server;
|
|
||||||
|
|
||||||
if ((ret = server.initialize()) != ERROR_SUCCESS) {
|
if ((ret = server.initialize()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ file
|
||||||
..\core\srs_core_auto_free.cpp,
|
..\core\srs_core_auto_free.cpp,
|
||||||
..\core\srs_core_server.hpp,
|
..\core\srs_core_server.hpp,
|
||||||
..\core\srs_core_server.cpp,
|
..\core\srs_core_server.cpp,
|
||||||
|
..\core\srs_core_reload.hpp,
|
||||||
|
..\core\srs_core_reload.cpp,
|
||||||
..\core\srs_core_config.hpp,
|
..\core\srs_core_config.hpp,
|
||||||
..\core\srs_core_config.cpp,
|
..\core\srs_core_config.cpp,
|
||||||
..\core\srs_core_refer.hpp,
|
..\core\srs_core_refer.hpp,
|
||||||
|
|
Loading…
Reference in a new issue