winlin

for #319, do not apply when config not changed.

@@ -67,9 +67,46 @@ using namespace _srs_internal; @@ -67,9 +67,46 @@ using namespace _srs_internal;
67 // '\r' 67 // '\r'
68 #define SRS_CR (char)SRS_CONSTS_CR 68 #define SRS_CR (char)SRS_CONSTS_CR
69 69
70 -// dumps the engine to amf0 object. 70 +/**
  71 + * dumps the ingest/transcode-engine in @param dir to amf0 object @param engine.
  72 + * @param dir the transcode or ingest config directive.
  73 + * @param engine the amf0 object to dumps to.
  74 + */
71 int srs_config_dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine); 75 int srs_config_dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine);
72 76
  77 +/**
  78 + * whether the two vector actual equals, for instance,
  79 + * srs_vector_actual_equals([0, 1, 2], [0, 1, 2]) ==== true
  80 + * srs_vector_actual_equals([0, 1, 2], [2, 1, 0]) ==== true
  81 + * srs_vector_actual_equals([0, 1, 2], [0, 2, 1]) ==== true
  82 + * srs_vector_actual_equals([0, 1, 2], [0, 1, 2, 3]) ==== false
  83 + * srs_vector_actual_equals([1, 2, 3], [0, 1, 2]) ==== false
  84 + */
  85 +template<typename T>
  86 +bool srs_vector_actual_equals(const vector<T>& a, const vector<T>& b)
  87 +{
  88 + // all elements of a in b.
  89 + for (int i = 0; i < (int)a.size(); i++) {
  90 + const T& e = a.at(i);
  91 + if (::find(b.begin(), b.end(), e) == b.end()) {
  92 + return false;
  93 + }
  94 + }
  95 +
  96 + // all elements of b in a.
  97 + for (int i = 0; i < (int)b.size(); i++) {
  98 + const T& e = b.at(i);
  99 + if (::find(a.begin(), a.end(), e) == a.end()) {
  100 + return false;
  101 + }
  102 + }
  103 +
  104 + return true;
  105 +}
  106 +
  107 +/**
  108 + * whether the ch is common space.
  109 + */
73 bool is_common_space(char ch) 110 bool is_common_space(char ch)
74 { 111 {
75 return (ch == ' ' || ch == '\t' || ch == SRS_CR || ch == SRS_LF); 112 return (ch == ' ' || ch == '\t' || ch == SRS_CR || ch == SRS_LF);
@@ -900,14 +937,9 @@ int SrsConfig::reload_conf(SrsConfig* conf) @@ -900,14 +937,9 @@ int SrsConfig::reload_conf(SrsConfig* conf)
900 937
901 // merge config: listen 938 // merge config: listen
902 if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) { 939 if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) {
903 - for (it = subscribes.begin(); it != subscribes.end(); ++it) {  
904 - ISrsReloadHandler* subscribe = *it;  
905 - if ((ret = subscribe->on_reload_listen()) != ERROR_SUCCESS) {  
906 - srs_error("notify subscribes reload listen failed. ret=%d", ret);  
907 - return ret;  
908 - } 940 + if ((ret = do_reload_listen()) != ERROR_SUCCESS) {
  941 + return ret;
909 } 942 }
910 - srs_trace("reload listen success.");  
911 } 943 }
912 944
913 // merge config: pid 945 // merge config: pid
@@ -2175,13 +2207,34 @@ int SrsConfig::raw_to_json(SrsAmf0Object* obj) @@ -2175,13 +2207,34 @@ int SrsConfig::raw_to_json(SrsAmf0Object* obj)
2175 return ret; 2207 return ret;
2176 } 2208 }
2177 2209
2178 -int SrsConfig::raw_set_listen(const vector<string>& eps) 2210 +int SrsConfig::raw_set_listen(const vector<string>& eps, bool& applied)
2179 { 2211 {
2180 int ret = ERROR_SUCCESS; 2212 int ret = ERROR_SUCCESS;
2181 2213
  2214 + applied = false;
  2215 +
2182 SrsConfDirective* listen = root->get("listen"); 2216 SrsConfDirective* listen = root->get("listen");
  2217 +
  2218 + // not changed, ignore.
  2219 + if (srs_vector_actual_equals(listen->args, eps)) {
  2220 + return ret;
  2221 + }
  2222 +
  2223 + // changed, apply and reload.
2183 listen->args = eps; 2224 listen->args = eps;
2184 2225
  2226 + if ((ret = do_reload_listen()) != ERROR_SUCCESS) {
  2227 + return ret;
  2228 + }
  2229 +
  2230 + applied = true;
  2231 + return ret;
  2232 +}
  2233 +
  2234 +int SrsConfig::do_reload_listen()
  2235 +{
  2236 + int ret = ERROR_SUCCESS;
  2237 +
2185 // force to reload the memory server. 2238 // force to reload the memory server.
2186 vector<ISrsReloadHandler*>::iterator it; 2239 vector<ISrsReloadHandler*>::iterator it;
2187 for (it = subscribes.begin(); it != subscribes.end(); ++it) { 2240 for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@@ -331,8 +331,14 @@ public: @@ -331,8 +331,14 @@ public:
331 virtual int raw_to_json(SrsAmf0Object* obj); 331 virtual int raw_to_json(SrsAmf0Object* obj);
332 /** 332 /**
333 * raw set the global listen. 333 * raw set the global listen.
  334 + * @param applied whether the config is applied.
334 */ 335 */
335 - virtual int raw_set_listen(const std::vector<std::string>& eps); 336 + virtual int raw_set_listen(const std::vector<std::string>& eps, bool& applied);
  337 +private:
  338 + /**
  339 + * do reload listen, for reload from signal or raw api.
  340 + */
  341 + virtual int do_reload_listen();
336 public: 342 public:
337 /** 343 /**
338 * get the config file path. 344 * get the config file path.
@@ -992,6 +992,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) @@ -992,6 +992,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
992 return srs_api_response_code(w, r, ret); 992 return srs_api_response_code(w, r, ret);
993 } 993 }
994 994
  995 + bool applied = false;
995 if (scope == "global.listen") { 996 if (scope == "global.listen") {
996 vector<string> eps = srs_string_split(value, ","); 997 vector<string> eps = srs_string_split(value, ",");
997 998
@@ -1010,14 +1011,19 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) @@ -1010,14 +1011,19 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
1010 return srs_api_response_code(w, r, ret); 1011 return srs_api_response_code(w, r, ret);
1011 } 1012 }
1012 1013
1013 - if ((ret = _srs_config->raw_set_listen(eps)) != ERROR_SUCCESS) { 1014 + if ((ret = _srs_config->raw_set_listen(eps, applied)) != ERROR_SUCCESS) {
1014 srs_error("raw api update global.listen=%s failed. ret=%d", value.c_str(), ret); 1015 srs_error("raw api update global.listen=%s failed. ret=%d", value.c_str(), ret);
1015 return srs_api_response_code(w, r, ret); 1016 return srs_api_response_code(w, r, ret);
1016 } 1017 }
1017 } 1018 }
1018 1019
1019 - server->on_signal(SRS_SIGNAL_PERSISTENCE_CONFIG);  
1020 - srs_trace("raw api update %s=%s ok.", scope.c_str(), value.c_str()); 1020 + // whether the config applied.
  1021 + if (applied) {
  1022 + server->on_signal(SRS_SIGNAL_PERSISTENCE_CONFIG);
  1023 + srs_trace("raw api update %s=%s ok.", scope.c_str(), value.c_str());
  1024 + } else {
  1025 + srs_warn("raw api update not applied %s=%s.", scope.c_str(), value.c_str());
  1026 + }
1021 1027
1022 return srs_api_response(w, r, obj->to_json()); 1028 return srs_api_response(w, r, obj->to_json());
1023 } 1029 }