winlin

support reload config(listen and chunk_size) by SIGHUP(1).

... ... @@ -48,6 +48,7 @@ url: rtmp://127.0.0.1:1935/live/livestream
* nginx v1.5.0: 139524 lines <br/>
### 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 config the chunk_size.
* v0.4, 2013-11-09, support pause for live stream.
... ...
# the listen ports, split by space.
listen 1935 19350;
listen 1935;
# the default chunk size is 128, max is 65536,
# some client does not support chunk size change,
# however, most clients supports it and it can improve
... ...
... ... @@ -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_stream" "srs_core_source" "srs_core_codec"
"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
CORE_OBJS="${MODULE_OBJS[@]}"
... ...
... ... @@ -84,4 +84,7 @@ extern int64_t srs_get_system_time_ms();
// the deamon st-thread will update it.
extern void srs_update_system_time_ms();
// signal defines.
#define SIGNAL_RELOAD SIGHUP
#endif
\ No newline at end of file
... ...
... ... @@ -34,8 +34,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <fcntl.h>
#include <vector>
#include <algorithm>
#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)
... ... @@ -79,7 +82,7 @@ int SrsFileBuffer::open(const char* filename)
assert(fd == -1);
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;
}
... ... @@ -182,21 +185,21 @@ int SrsConfDirective::parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type)
}
if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) {
if (type != parse_block) {
fprintf(stderr, "line %d: unexpected \"}\"\n", buffer->line);
srs_error("line %d: unexpected \"}\"", buffer->line);
return ret;
}
return ERROR_SUCCESS;
}
if (ret == ERROR_SYSTEM_CONFIG_EOF) {
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 ERROR_SUCCESS;
}
if (args.empty()) {
fprintf(stderr, "line %d: empty directive.\n", buffer->line);
srs_error("line %d: empty directive.", buffer->line);
return ret;
}
... ... @@ -239,7 +242,7 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
while (true) {
if ((ret = refill_buffer(buffer, d_quoted, s_quoted, startline, pstart)) != ERROR_SUCCESS) {
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 ret;
... ... @@ -268,7 +271,7 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
if (ch == '{') {
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;
}
... ... @@ -282,19 +285,19 @@ int SrsConfDirective::read_token(SrsFileBuffer* buffer, std::vector<std::string>
switch (ch) {
case ';':
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_DIRECTIVE;
case '{':
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_BLOCK_START;
case '}':
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_BLOCK_END;
... ... @@ -376,12 +379,12 @@ int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s
buffer->line = startline;
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);
} else {
fprintf(stderr, "line %d: too long parameter, "
"probably missing terminating '%c' character\n", buffer->line, d_quoted? '"':'\'');
srs_error("line %d: too long parameter, "
"probably missing terminating '%c' character", buffer->line, d_quoted? '"':'\'');
}
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));
int n = read(buffer->fd, buffer->start + len, 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;
}
... ... @@ -404,26 +407,85 @@ int SrsConfDirective::refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s
return ret;
}
Config* config = new Config();
SrsConfig* config = new SrsConfig();
Config::Config()
SrsConfig::SrsConfig()
{
show_help = false;
show_version = false;
config_file = NULL;
root = new SrsConfDirective();
root->conf_line = 0;
root->name = "root";
}
Config::~Config()
SrsConfig::~SrsConfig()
{
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
int Config::parse_options(int argc, char** argv)
int SrsConfig::parse_options(int argc, char** argv)
{
int ret = ERROR_SUCCESS;
... ... @@ -438,33 +500,23 @@ int Config::parse_options(int argc, char** argv)
}
if (show_version) {
fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);
printf("%s\n", RTMP_SIG_SRS_VERSION);
}
if (show_help || show_version) {
exit(0);
}
if (!config_file) {
fprintf(stderr, "config file not specified, see help: %s -h\n", argv[0]);
return ERROR_SYSTEM_CONFIG_INVALID;
}
if ((ret = root->parse(config_file)) != ERROR_SUCCESS) {
if (config_file.empty()) {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret);
return ret;
}
SrsConfDirective* conf = NULL;
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;
return parse_file(config_file.c_str());
}
SrsConfDirective* Config::get_vhost(std::string vhost)
SrsConfDirective* SrsConfig::get_vhost(std::string vhost)
{
srs_assert(root);
... ... @@ -487,7 +539,7 @@ SrsConfDirective* Config::get_vhost(std::string vhost)
return NULL;
}
SrsConfDirective* Config::get_gop_cache(std::string vhost)
SrsConfDirective* SrsConfig::get_gop_cache(std::string vhost)
{
SrsConfDirective* conf = get_vhost(vhost);
... ... @@ -498,7 +550,7 @@ SrsConfDirective* Config::get_gop_cache(std::string vhost)
return conf->get("gop_cache");
}
SrsConfDirective* Config::get_refer(std::string vhost)
SrsConfDirective* SrsConfig::get_refer(std::string vhost)
{
SrsConfDirective* conf = get_vhost(vhost);
... ... @@ -509,7 +561,7 @@ SrsConfDirective* Config::get_refer(std::string vhost)
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);
... ... @@ -520,7 +572,7 @@ SrsConfDirective* Config::get_refer_play(std::string vhost)
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);
... ... @@ -531,26 +583,52 @@ SrsConfDirective* Config::get_refer_publish(std::string vhost)
return conf->get("refer_publish");
}
SrsConfDirective* Config::get_listen()
SrsConfDirective* SrsConfig::get_listen()
{
return root->get("listen");
}
SrsConfDirective* Config::get_chunk_size()
SrsConfDirective* SrsConfig::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;
char* p = argv[i];
if (*p++ != '-') {
fprintf(stderr, "invalid options(index=%d, value=%s), "
"must starts with -, see help: %s -h\n", i, argv[i], argv[0]);
return ERROR_SYSTEM_CONFIG_INVALID;
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("invalid options(index=%d, value=%s), "
"must starts with -, see help: %s -h, ret=%d", i, argv[i], argv[0], ret);
return ret;
}
while (*p) {
... ... @@ -572,20 +650,22 @@ int Config::parse_argv(int& i, char** argv)
config_file = argv[i];
return ret;
}
fprintf(stderr, "option \"-c\" requires parameter\n");
return ERROR_SYSTEM_CONFIG_INVALID;
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("option \"-c\" requires parameter, ret=%d", ret);
return ret;
default:
fprintf(stderr, "invalid option: \"%c\", see help: %s -h\n", *(p - 1), argv[0]);
return ERROR_SYSTEM_CONFIG_INVALID;
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("invalid option: \"%c\", see help: %s -h, ret=%d", *(p - 1), argv[0], 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"
"Usage: %s [-h?vV] [-c <filename>]\n"
"\n"
... ... @@ -600,3 +680,39 @@ void Config::print_help(char** argv)
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 <string>
#include <srs_core_reload.hpp>
// default vhost for rtmp
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
... ... @@ -84,16 +86,21 @@ public:
/**
* the config parser.
*/
class Config
class SrsConfig
{
private:
bool show_help;
bool show_version;
char* config_file;
std::string config_file;
SrsConfDirective* root;
std::vector<SrsReloadHandler*> subscribes;
public:
SrsConfig();
virtual ~SrsConfig();
public:
Config();
virtual ~Config();
virtual int reload();
virtual void subscribe(SrsReloadHandler* handler);
virtual void unsubscribe(SrsReloadHandler* handler);
public:
virtual int parse_options(int argc, char** argv);
virtual SrsConfDirective* get_vhost(std::string vhost);
... ... @@ -104,11 +111,17 @@ public:
virtual SrsConfDirective* get_listen();
virtual SrsConfDirective* get_chunk_size();
private:
virtual int parse_file(const char* filename);
virtual int parse_argv(int& i, char** argv);
virtual void print_help(char** argv);
};
/**
* deep compare directive.
*/
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b);
// global config
extern Config* config;
extern SrsConfig* config;
#endif
\ No newline at end of file
... ...
... ... @@ -36,8 +36,13 @@ SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
SrsConnection::~SrsConnection()
{
if (stfd) {
int fd = st_netfd_fileno(stfd);
st_netfd_close(stfd);
stfd = NULL;
// st does not close it sometimes,
// close it manually.
close(fd);
}
}
... ...
/*
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;
}
... ...
/*
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
\ No newline at end of file
... ...
... ... @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <algorithm>
... ... @@ -37,7 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_config.hpp>
#define SERVER_LISTEN_BACKLOG 10
#define SRS_TIME_RESOLUTION_MS 1000
#define SRS_TIME_RESOLUTION_MS 500
SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
{
... ... @@ -47,6 +48,9 @@ SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
port = 0;
server = _server;
type = _type;
tid = NULL;
loop = false;
}
SrsListener::~SrsListener()
... ... @@ -55,6 +59,17 @@ SrsListener::~SrsListener()
st_netfd_close(stfd);
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)
... ... @@ -103,7 +118,7 @@ int SrsListener::listen(int _port)
}
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;
srs_error("st_thread_create listen thread error. ret=%d", ret);
return ret;
... ... @@ -122,7 +137,7 @@ void SrsListener::listen_cycle()
log_context->generate_id();
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);
if(client_stfd == NULL){
... ... @@ -146,6 +161,7 @@ void* SrsListener::listen_thread(void* arg)
SrsListener* obj = (SrsListener*)arg;
srs_assert(obj != NULL);
obj->loop = true;
obj->listen_cycle();
return NULL;
... ... @@ -153,10 +169,15 @@ void* SrsListener::listen_thread(void* arg)
SrsServer::SrsServer()
{
signal_reload = false;
config->subscribe(this);
}
SrsServer::~SrsServer()
{
config->unsubscribe(this);
if (true) {
std::vector<SrsConnection*>::iterator it;
for (it = conns.begin(); it != conns.end(); ++it) {
... ... @@ -166,14 +187,7 @@ SrsServer::~SrsServer()
conns.clear();
}
if (true) {
std::vector<SrsListener*>::iterator it;
for (it = listeners.begin(); it != listeners.end(); ++it) {
SrsListener* listener = *it;
srs_freep(listener);
}
listeners.clear();
}
close_listeners();
}
int SrsServer::initialize()
... ... @@ -212,6 +226,8 @@ int SrsServer::listen()
conf = config->get_listen();
srs_assert(conf);
close_listeners();
for (int i = 0; i < (int)conf->args.size(); i++) {
SrsListener* listener = new SrsListener(this, SrsListenerStream);
listeners.push_back(listener);
... ... @@ -234,6 +250,17 @@ int SrsServer::cycle()
while (true) {
st_usleep(SRS_TIME_RESOLUTION_MS * 1000);
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;
... ... @@ -254,6 +281,23 @@ void SrsServer::remove(SrsConnection* 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 ret = ERROR_SUCCESS;
... ... @@ -279,3 +323,10 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
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 <srs_core_reload.hpp>
class SrsServer;
class SrsConnection;
... ... @@ -52,6 +54,8 @@ private:
st_netfd_t stfd;
int port;
SrsServer* server;
st_thread_t tid;
bool loop;
public:
SrsListener(SrsServer* _server, SrsListenerType _type);
virtual ~SrsListener();
... ... @@ -62,12 +66,13 @@ private:
static void* listen_thread(void* arg);
};
class SrsServer
class SrsServer : public SrsReloadHandler
{
friend class SrsListener;
private:
std::vector<SrsConnection*> conns;
std::vector<SrsListener*> listeners;
bool signal_reload;
public:
SrsServer();
virtual ~SrsServer();
... ... @@ -76,8 +81,14 @@ public:
virtual int listen();
virtual int cycle();
virtual void remove(SrsConnection* conn);
virtual void on_signal(int signo);
private:
virtual void close_listeners();
virtual int accept_client(SrsListenerType type, st_netfd_t client_stfd);
public:
virtual int on_reload_listen();
};
extern SrsServer server;
#endif
\ No newline at end of file
... ...
... ... @@ -27,16 +27,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_config.hpp>
#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 ret = ERROR_SUCCESS;
signal(SIGNAL_RELOAD, handler);
if ((ret = config->parse_options(argc, argv)) != ERROR_SUCCESS) {
return ret;
}
SrsServer server;
if ((ret = server.initialize()) != ERROR_SUCCESS) {
return ret;
}
... ...
... ... @@ -10,6 +10,8 @@ file
..\core\srs_core_auto_free.cpp,
..\core\srs_core_server.hpp,
..\core\srs_core_server.cpp,
..\core\srs_core_reload.hpp,
..\core\srs_core_reload.cpp,
..\core\srs_core_config.hpp,
..\core\srs_core_config.cpp,
..\core\srs_core_refer.hpp,
... ...