From 3ba11441a1126568db28026e4a047beeadbcda45 Mon Sep 17 00:00:00 2001
From: Thulinma <jaron@vietors.com>
Date: Wed, 14 Oct 2015 10:25:58 +0200
Subject: [PATCH] Improved flow of controller main function, made config file
 only re-write if updates were actually necessary, failure to open a stream
 input now fails the output correctly.

---
 src/controller/controller.cpp         | 16 +++++++++-------
 src/controller/controller_storage.cpp | 22 ++++++++++++++++++----
 src/output/output.cpp                 |  3 +++
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp
index 675f569c..05e1809f 100644
--- a/src/controller/controller.cpp
+++ b/src/controller/controller.cpp
@@ -268,23 +268,25 @@ int main(int argc, char ** argv){
   //start main loop
   Controller::conf.serveThreadedSocket(Controller::handleAPIConnection);
   //print shutdown reason
+  std::string shutdown_reason;
   if (!Controller::conf.is_active){
-    Controller::Log("CONF", "Controller shutting down because of user request (received shutdown signal)");
+    shutdown_reason = "user request (received shutdown signal)";
   }else{
-    Controller::Log("CONF", "Controller shutting down because of socket problem (API port closed)");
+    shutdown_reason = "socket problem (API port closed)";
   }
+  Controller::Log("CONF", "Controller shutting down because of "+shutdown_reason);
   Controller::conf.is_active = false;
   //join all joinable threads
   statsThread.join();
   monitorThread.join();
   //write config
+  tthread::lock_guard<tthread::mutex> guard(Controller::logMutex);
+  Controller::Storage.removeMember("log");
+  jsonForEach(Controller::Storage["streams"], it) {
+    it->removeMember("meta");
+  }
   if ( !Controller::WriteFile(Controller::conf.getString("configFile"), Controller::Storage.toString())){
     std::cerr << "Error writing config " << Controller::conf.getString("configFile") << std::endl;
-    tthread::lock_guard<tthread::mutex> guard(Controller::logMutex);
-    Controller::Storage.removeMember("log");
-    jsonForEach(Controller::Storage["streams"], it) {
-      it->removeMember("meta");
-    }
     std::cerr << "**Config**" << std::endl;
     std::cerr << Controller::Storage.toString() << std::endl;
     std::cerr << "**End config**" << std::endl;
diff --git a/src/controller/controller_storage.cpp b/src/controller/controller_storage.cpp
index 68a0770f..fab608cb 100644
--- a/src/controller/controller_storage.cpp
+++ b/src/controller/controller_storage.cpp
@@ -76,10 +76,24 @@ namespace Controller {
   
   /// Writes the current config to shared memory to be used in other processes
   void writeConfig(){
-    JSON::Value writeConf;
-    writeConf["config"] = Storage["config"];
-    writeConf["streams"] = Storage["streams"];
-    writeConf["capabilities"] = capabilities;
+    static JSON::Value writeConf;
+    bool changed = false;
+    if (writeConf["config"] != Storage["config"]){
+      writeConf["config"] = Storage["config"];
+      VERYHIGH_MSG("Saving new config because of edit in server config structure");
+      changed = true;
+    }
+    if (writeConf["streams"] != Storage["streams"]){
+      writeConf["streams"] = Storage["streams"];
+      VERYHIGH_MSG("Saving new config because of edit in streams");
+      changed = true;
+    }
+    if (writeConf["capabilities"] != capabilities){
+      writeConf["capabilities"] = capabilities;
+      VERYHIGH_MSG("Saving new config because of edit in capabilities");
+      changed = true;
+    }
+    if (!changed){return;}//cancel further processing if no changes
 
     static IPC::sharedPage mistConfOut("!mistConfig", DEFAULT_CONF_PAGE_SIZE, true);
     IPC::semaphore configLock("!mistConfLock", O_CREAT | O_RDWR, ACCESSPERMS, 1);
diff --git a/src/output/output.cpp b/src/output/output.cpp
index 85b3bf72..fe090486 100644
--- a/src/output/output.cpp
+++ b/src/output/output.cpp
@@ -85,6 +85,9 @@ namespace Mist {
   /// thus causing the process to exit cleanly.
   void Output::onFail(){
     isInitialized = false;
+    wantRequest = true;
+    parseData= false;
+    streamName.clear();
     myConn.close();
   }