From 243a05c8af9457ad5a71d2fc4742d8f8d2db238b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 16 Apr 2015 12:23:03 +0200 Subject: [PATCH] Removed unused code from procs library, updated and simplified connector handler in controller. --- lib/procs.cpp | 400 +---------------------- lib/procs.h | 21 +- lib/shared_memory.cpp | 6 +- src/controller/controller_connectors.cpp | 68 ++-- 4 files changed, 56 insertions(+), 439 deletions(-) diff --git a/lib/procs.cpp b/lib/procs.cpp index 8bec4a33..9d51b3d4 100644 --- a/lib/procs.cpp +++ b/lib/procs.cpp @@ -21,8 +21,7 @@ #include #include "timing.h" -std::map Util::Procs::plist; -std::map Util::Procs::exitHandlers; +std::set Util::Procs::plist; bool Util::Procs::handler_set = false; @@ -39,7 +38,7 @@ static bool childRunning(pid_t p) { } /// sends sig 0 to process (pid). returns true if process is running -bool Util::Procs::isRunnning(pid_t pid){ +bool Util::Procs::isRunning(pid_t pid){ return !kill(pid, 0); } @@ -49,8 +48,8 @@ bool Util::Procs::isRunnning(pid_t pid){ /// all remaining children. Waits one more second for cleanup to finish, then exits. void Util::Procs::exit_handler() { int waiting = 0; - std::map listcopy = plist; - std::map::iterator it; + std::set listcopy = plist; + std::set::iterator it; if (listcopy.empty()) { return; } @@ -58,7 +57,7 @@ void Util::Procs::exit_handler() { //wait up to 0.5 second for applications to shut down while (!listcopy.empty() && waiting <= 25) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -76,8 +75,8 @@ void Util::Procs::exit_handler() { //send sigint to all remaining if (!listcopy.empty()) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - DEBUG_MSG(DLVL_DEVEL, "SIGINT %d: %s", (*it).first, (*it).second.c_str()); - kill((*it).first, SIGINT); + DEBUG_MSG(DLVL_DEVEL, "SIGINT %d", *it); + kill(*it, SIGINT); } } @@ -86,7 +85,7 @@ void Util::Procs::exit_handler() { //wait up to 5 seconds for applications to shut down while (!listcopy.empty() && waiting <= 250) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -104,8 +103,8 @@ void Util::Procs::exit_handler() { //send sigkill to all remaining if (!listcopy.empty()) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d: %s", (*it).first, (*it).second.c_str()); - kill((*it).first, SIGKILL); + DEBUG_MSG(DLVL_DEVEL, "SIGKILL %d", *it); + kill(*it, SIGKILL); } } @@ -114,7 +113,7 @@ void Util::Procs::exit_handler() { //wait up to 1 second for applications to shut down while (!listcopy.empty() && waiting <= 50) { for (it = listcopy.begin(); it != listcopy.end(); it++) { - if (!childRunning((*it).first)) { + if (!childRunning(*it)) { listcopy.erase(it); break; } @@ -170,23 +169,15 @@ void Util::Procs::childsig_handler(int signum) { return; } -#if DEBUG >= DLVL_HIGH - std::string pname = plist[ret]; -#endif plist.erase(ret); #if DEBUG >= DLVL_HIGH if (!isActive(pname)) { - DEBUG_MSG(DLVL_HIGH, "Process %s fully terminated", pname.c_str()); + DEBUG_MSG(DLVL_HIGH, "Process %d fully terminated", ret); } else { DEBUG_MSG(DLVL_HIGH, "Child process %d exited", ret); } #endif - if (exitHandlers.count(ret) > 0) { - TerminationNotifier tn = exitHandlers[ret]; - exitHandlers.erase(ret); - tn(ret, exitcode); - } } } @@ -195,8 +186,8 @@ void Util::Procs::childsig_handler(int signum) { std::string Util::Procs::getOutputOf(char * const * argv) { std::string ret; int fin = 0, fout = -1, ferr = 0; - StartPiped("output_getter", argv, &fin, &fout, &ferr); - while (isActive("output_getter")) { + pid_t myProc = StartPiped(argv, &fin, &fout, &ferr); + while (isActive(myProc)) { Util::sleep(100); } FILE * outFile = fdopen(fout, "r"); @@ -210,258 +201,12 @@ std::string Util::Procs::getOutputOf(char * const * argv) { return ret; } -/// Runs the given command and returns the stdout output as a string. -std::string Util::Procs::getOutputOf(std::string cmd) { - std::string ret; - int fin = 0, fout = -1, ferr = 0; - StartPiped("output_getter", cmd, &fin, &fout, &ferr); - while (isActive("output_getter")) { - Util::sleep(100); - } - FILE * outFile = fdopen(fout, "r"); - char * fileBuf = 0; - size_t fileBufLen = 0; - while (!(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)) { - ret += fileBuf; - } - free(fileBuf); - fclose(outFile); - return ret; -} - - -/// Attempts to run the command cmd. -/// Replaces the current process - use after forking first! -/// This function will never return - it will either run the given -/// command or kill itself with return code 42. -void Util::Procs::runCmd(std::string & cmd) { - //split cmd into arguments - //supports a maximum of 20 arguments - char * tmp = (char *)cmd.c_str(); - char * tmp2 = 0; - char * args[21]; - int i = 0; - tmp2 = strtok(tmp, " "); - args[0] = tmp2; - while (tmp2 != 0 && (i < 20)) { - tmp2 = strtok(0, " "); - ++i; - args[i] = tmp2; - } - if (i == 20) { - args[20] = 0; - } - //execute the command - execvp(args[0], args); - DEBUG_MSG(DLVL_ERROR, "Error running %s: %s", cmd.c_str(), strerror(errno)); - _exit(42); -} - -/// Starts a new process if the name is not already active. -/// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for this process. -pid_t Util::Procs::Start(std::string name, std::string cmd) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - pid_t ret = fork(); - if (ret == 0) { - runCmd(cmd); - } else { - if (ret > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PID %d: %s", name.c_str(), ret, cmd.c_str()); - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started: fork() failed", name.c_str()); - return 0; - } - } - return ret; -} - -/// Starts two piped processes if the name is not already active. -/// \return 0 if process was not started, sub (sending) process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for sub (sending) process. -/// \arg cmd2 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - int pfildes[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - - int devnull = open("/dev/null", O_RDWR); - pid_t ret = fork(); - if (ret == 0) { - close(pfildes[0]); - dup2(pfildes[1], STDOUT_FILENO); - close(pfildes[1]); - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd); - } else { - if (ret > 0) { - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - } - - pid_t ret2 = fork(); - if (ret2 == 0) { - close(pfildes[1]); - dup2(pfildes[0], STDIN_FILENO); - close(pfildes[0]); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd2); - } else { - if (ret2 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); - plist.insert(std::pair(ret2, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - } - close(pfildes[1]); - close(pfildes[0]); - return ret; -} - -/// Starts three piped processes if the name is not already active. -/// \return 0 if process was not started, sub (sending) process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Commandline for sub (sending) process. -/// \arg cmd2 Commandline for sub (middle) process. -/// \arg cmd3 Commandline for main (receiving) process. -pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3) { - if (isActive(name)) { - return getPid(name); - } - setHandler(); - int pfildes[2]; - int pfildes2[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - if (pipe(pfildes2) == -1) { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. Pipe creation failed.", name.c_str()); - return 0; - } - - int devnull = open("/dev/null", O_RDWR); - pid_t ret = fork(); - if (ret == 0) { - close(pfildes[0]); - dup2(pfildes[1], STDOUT_FILENO); - close(pfildes[1]); - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDERR_FILENO); - close(pfildes2[1]); - close(pfildes2[0]); - runCmd(cmd); - } else { - if (ret > 0) { - plist.insert(std::pair(ret, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - - pid_t ret2 = fork(); - if (ret2 == 0) { - close(pfildes[1]); - close(pfildes2[0]); - dup2(pfildes[0], STDIN_FILENO); - close(pfildes[0]); - dup2(pfildes2[1], STDOUT_FILENO); - close(pfildes2[1]); - dup2(devnull, STDERR_FILENO); - runCmd(cmd2); - } else { - if (ret2 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d): %s | %s", name.c_str(), ret, ret2, cmd.c_str(), cmd2.c_str()); - plist.insert(std::pair(ret2, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - close(pfildes[1]); - close(pfildes[0]); - - pid_t ret3 = fork(); - if (ret3 == 0) { - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - dup2(pfildes2[0], STDIN_FILENO); - close(pfildes2[0]); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - runCmd(cmd3); - } else { - if (ret3 > 0) { - DEBUG_MSG(DLVL_HIGH, "Process %s started, PIDs (%d, %d, %d): %s | %s | %s", name.c_str(), ret, ret2, ret3, cmd.c_str(), cmd2.c_str(), cmd3.c_str()); - plist.insert(std::pair(ret3, name)); - } else { - DEBUG_MSG(DLVL_ERROR, "Process %s could not be started. fork() failed.", name.c_str()); - Stop(name); - close(pfildes[1]); - close(pfildes[0]); - close(pfildes2[1]); - close(pfildes2[0]); - return 0; - } - } - - return ret3; -} - /// Starts a new process with given fds if the name is not already active. /// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. /// \arg argv Command for this process. /// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. /// \arg fdout Same as fdin, but for stdout. /// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr) { - if (isActive(name)) { - DEBUG_MSG(DLVL_WARN, "Process %s already active - skipping start", name.c_str()); - return getPid(name); - } - int pidtemp = StartPiped(argv, fdin, fdout, fderr); - if (pidtemp > 0) { - plist.insert(std::pair(pidtemp, name)); - } - return pidtemp; -} - pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr) { pid_t pid; int pipein[2], pipeout[2], pipeerr[2]; @@ -574,6 +319,7 @@ pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int } return 0; } else { //parent + plist.insert(pid); DEBUG_MSG(DLVL_HIGH, "Piped process %s started, PID %d", argv[0], pid); if (devnull != -1) { close(devnull); @@ -594,70 +340,6 @@ pid_t Util::Procs::StartPiped(char * const * argv, int * fdin, int * fdout, int return pid; } -/// Starts a new process with given fds if the name is not already active. -/// \return 0 if process was not started, process PID otherwise. -/// \arg name Name for this process - only used internally. -/// \arg cmd Command for this process. -/// \arg fdin Standard input file descriptor. If null, /dev/null is assumed. Otherwise, if arg contains -1, a new fd is automatically allocated and written into this arg. Then the arg will be used as fd. -/// \arg fdout Same as fdin, but for stdout. -/// \arg fdout Same as fdin, but for stderr. -pid_t Util::Procs::StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr) { - //Convert the given command to a char * [] - char * tmp = (char *)cmd.c_str(); - char * tmp2 = 0; - char * args[21]; - int i = 0; - tmp2 = strtok(tmp, " "); - args[0] = tmp2; - while (tmp2 != 0 && (i < 20)) { - tmp2 = strtok(0, " "); - ++i; - args[i] = tmp2; - } - if (i == 20) { - args[20] = 0; - } - return StartPiped(name, args, fdin, fdout, fderr); -} - - -pid_t Util::Procs::StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2) { - int pfildes[2]; - if (pipe(pfildes) == -1) { - DEBUG_MSG(DLVL_ERROR, "Pipe creation failed for process %s", name.c_str()); - return 0; - } - pid_t res1 = StartPiped(name, cmd1, fdin, &pfildes[1], fderr1); - if (!res1) { - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - pid_t res2 = StartPiped(name + "receiving", cmd2, &pfildes[0], fdout, fderr2); - if (!res2) { - Stop(res1); - close(pfildes[1]); - close(pfildes[0]); - return 0; - } - //we can close these because the fork in StartPiped() copies them. - close(pfildes[1]); - close(pfildes[0]); - return res1; -} -/// Stops the named process, if running. -/// \arg name (Internal) name of process to stop -void Util::Procs::Stop(std::string name) { - int max = 5; - while (isActive(name)) { - Stop(getPid(name)); - max--; - if (max <= 0) { - return; - } - } -} - /// Stops the process with this pid, if running. /// \arg name The PID of the process to stop. void Util::Procs::Stop(pid_t name) { @@ -672,10 +354,10 @@ void Util::Procs::Murder(pid_t name) { /// (Attempts to) stop all running child processes. void Util::Procs::StopAll() { - std::map listcopy = plist; - std::map::iterator it; + std::set listcopy = plist; + std::set::iterator it; for (it = listcopy.begin(); it != listcopy.end(); it++) { - Stop((*it).first); + Stop(*it); } } @@ -684,54 +366,8 @@ int Util::Procs::Count() { return plist.size(); } -/// Returns true if a process by this name is currently active. -bool Util::Procs::isActive(std::string name) { - std::map listcopy = plist; - std::map::iterator it; - for (it = listcopy.begin(); it != listcopy.end(); it++) { - if ((*it).second == name) { - if (childRunning((*it).first)) { - return true; - } else { - plist.erase((*it).first); - } - } - } - return false; -} - /// Returns true if a process with this PID is currently active. bool Util::Procs::isActive(pid_t name) { return (plist.count(name) == 1) && (kill(name, 0) == 0); } -/// Gets PID for this named process, if active. -/// \return NULL if not active, process PID otherwise. -pid_t Util::Procs::getPid(std::string name) { - std::map::iterator it; - for (it = plist.begin(); it != plist.end(); it++) { - if ((*it).second == name) { - return (*it).first; - } - } - return 0; -} - -/// Gets name for this process PID, if active. -/// \return Empty string if not active, name otherwise. -std::string Util::Procs::getName(pid_t name) { - if (plist.count(name) == 1) { - return plist[name]; - } - return ""; -} - -/// Registers one notifier function for when a process indentified by PID terminates. -/// \return true if the notifier could be registered, false otherwise. -bool Util::Procs::SetTerminationNotifier(pid_t pid, TerminationNotifier notifier) { - if (plist.find(pid) != plist.end()) { - exitHandlers[pid] = notifier; - return true; - } - return false; -} diff --git a/lib/procs.h b/lib/procs.h index 4a90e233..4a06c5f0 100644 --- a/lib/procs.h +++ b/lib/procs.h @@ -4,19 +4,16 @@ #pragma once #include #include -#include +#include #include /// Contains utility code, not directly related to streaming media namespace Util { - typedef void (*TerminationNotifier)(pid_t pid, int exitCode); - /// Deals with spawning, monitoring and stopping child processes class Procs { private: - static std::map plist; ///< Holds active processes - static std::map exitHandlers; ///< termination function, if any + static std::set plist; ///< Holds active processes static bool handler_set; ///< If true, the sigchld handler has been setup. static void childsig_handler(int signum); static void exit_handler(); @@ -24,25 +21,13 @@ namespace Util { static void setHandler(); public: static std::string getOutputOf(char * const * argv); - static std::string getOutputOf(std::string cmd); - static pid_t Start(std::string name, std::string cmd); - static pid_t Start(std::string name, std::string cmd, std::string cmd2); - static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3); static pid_t StartPiped(char * const * argv, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped(std::string name, char * const * argv, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped(std::string name, std::string cmd, int * fdin, int * fdout, int * fderr); - static pid_t StartPiped2(std::string name, std::string cmd1, std::string cmd2, int * fdin, int * fdout, int * fderr1, int * fderr2); - static void Stop(std::string name); static void Stop(pid_t name); static void Murder(pid_t name); static void StopAll(); static int Count(); - static bool isActive(std::string name); static bool isActive(pid_t name); - static bool isRunnning(pid_t pid); - static pid_t getPid(std::string name); - static std::string getName(pid_t name); - static bool SetTerminationNotifier(pid_t pid, TerminationNotifier notifier); + static bool isRunning(pid_t pid); }; } diff --git a/lib/shared_memory.cpp b/lib/shared_memory.cpp index 42d48cf4..73c2d667 100644 --- a/lib/shared_memory.cpp +++ b/lib/shared_memory.cpp @@ -305,12 +305,12 @@ namespace IPC { } while (i < 10 && !handle && autoBackoff); } if (!handle) { - FAIL_MSG("%s for page %s failed: %s", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), strerror(errno)); + FAIL_MSG("%s for page %s failed with error code %u", (master ? "CreateFileMapping" : "OpenFileMapping"), name.c_str(), GetLastError()); return; } mapped = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!mapped) { - FAIL_MSG("MapViewOfFile for page %s failed: %s", name.c_str(), strerror(errno)); + FAIL_MSG("MapViewOfFile for page %s failed with error code %u", name.c_str(), GetLastError()); return; } //Under cygwin, the extra 4 bytes contain the real size of the page. @@ -740,7 +740,7 @@ namespace IPC { DEBUG_MSG(DLVL_VERYHIGH, "Shared memory %s is now at count %u", baseName.c_str(), amount); } unsigned short tmpPID = *((unsigned short *)(it->mapped+1+offset+payLen-2)); - if(!Util::Procs::isRunnning(tmpPID) && !(*counter == 126 || *counter == 127 || *counter == 254 || *counter == 255)){ + if(!Util::Procs::isRunning(tmpPID) && !(*counter == 126 || *counter == 127 || *counter == 254 || *counter == 255)){ WARN_MSG("process disappeared, timing out. (pid %d)", tmpPID); *counter = 126; //if process is already dead, instant timeout. } diff --git a/src/controller/controller_connectors.cpp b/src/controller/controller_connectors.cpp index 191cbcd9..a1e8faa9 100644 --- a/src/controller/controller_connectors.cpp +++ b/src/controller/controller_connectors.cpp @@ -18,21 +18,16 @@ ///\brief Holds everything unique to the controller. namespace Controller { - static std::map currentConnectors; /// currentConnectors; ///::iterator iter; + std::map::iterator iter; for (iter = currentConnectors.begin(); iter != currentConnectors.end(); iter++){ - if (iter->second.substr(0, protocol.size()) == protocol){ - Log("CONF", "Killing connector for update: " + iter->second); - Util::Procs::Stop(toConn(iter->first)); + if (iter->first.substr(0, protocol.size()) == protocol){ + Log("CONF", "Killing connector for update: " + iter->first); + Util::Procs::Stop(iter->second); } } } @@ -65,7 +60,8 @@ namespace Controller { } } - static inline void buildPipedArguments(JSON::Value & p, char * argarr[], JSON::Value & capabilities){ + static inline void buildPipedArguments(const std::string & proto, char * argarr[], JSON::Value & capabilities){ + JSON::Value p = JSON::fromString(proto); int argnum = 0; static std::string tmparg; tmparg = Util::getMyPath() + std::string("MistOut") + p["connector"].asStringRef(); @@ -82,12 +78,11 @@ namespace Controller { if (pipedCapa.isMember("optional")){builPipedPart(p, argarr, argnum, pipedCapa["optional"]);} } - ///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary. + ///\brief Checks current protocol configuration, updates state of enabled connectors if neccessary. ///\param p An object containing all protocols. ///\param capabilities An object containing the detected capabilities. void CheckProtocols(JSON::Value & p, JSON::Value & capabilities){ - std::map new_connectors; - std::map::iterator iter; + std::set runningConns; // used for building args int zero = 0; @@ -102,12 +97,13 @@ namespace Controller { for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){ counter = ait - p.ArrBegin(); std::string prevOnline = ( *ait)["online"].asString(); - #define connName (*ait)["connector"].asStringRef() + const std::string & connName = (*ait)["connector"].asStringRef(); + //do not further parse if there's no connector name if ( !(*ait).isMember("connector") || connName == ""){ ( *ait)["online"] = "Missing connector name"; continue; } - + //ignore connectors that are not installed if ( !capabilities["connectors"].isMember(connName)){ ( *ait)["online"] = "Not installed"; if (( *ait)["online"].asString() != prevOnline){ @@ -115,14 +111,13 @@ namespace Controller { } continue; } - - #define connCapa capabilities["connectors"][connName] - + //list connectors that go through HTTP as 'enabled' without actually running them. + JSON::Value & connCapa = capabilities["connectors"][connName]; if (connCapa.isMember("socket") || (connCapa.isMember("deps") && connCapa["deps"].asStringRef() == "HTTP")){ ( *ait)["online"] = "Enabled"; continue; } - + //check required parameters, skip if anything is missing if (connCapa.isMember("required")){ bool gotAll = true; for (JSON::ObjIter it = connCapa["required"].ObjBegin(); it != connCapa["required"].ObjEnd(); ++it){ @@ -137,12 +132,13 @@ namespace Controller { } if (!gotAll){continue;} } - + //remove current online status ( *ait).removeMember("online"); /// \todo Check dependencies? - - new_connectors[counter] = (*ait).toString(); - if (Util::Procs::isActive(toConn(counter))){ + //set current online status + std::string myCmd = (*ait).toString(); + runningConns.insert(myCmd); + if (currentConnectors.count(myCmd) && Util::Procs::isActive(currentConnectors[myCmd])){ ( *ait)["online"] = 1; }else{ ( *ait)["online"] = 0; @@ -150,28 +146,28 @@ namespace Controller { } //shut down deleted/changed connectors - for (iter = currentConnectors.begin(); iter != currentConnectors.end(); iter++){ - if (new_connectors.count(iter->first) != 1 || new_connectors[iter->first] != iter->second){ - Log("CONF", "Stopping connector " + iter->second); - Util::Procs::Stop(toConn(iter->first)); + std::map::iterator it; + for (it = currentConnectors.begin(); it != currentConnectors.end(); it++){ + if (!runningConns.count(it->first)){ + Log("CONF", "Stopping connector " + it->first); + Util::Procs::Stop(it->second); } } //start up new/changed connectors - for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){ - if (currentConnectors.count(iter->first) != 1 || currentConnectors[iter->first] != iter->second || !Util::Procs::isActive(toConn(iter->first))){ - Log("CONF", "Starting connector: " + iter->second); + while (runningConns.size() && conf.is_active){ + if (!currentConnectors.count(*runningConns.begin()) || !Util::Procs::isActive(currentConnectors[*runningConns.begin()])){ + Log("CONF", "Starting connector: " + *runningConns.begin()); // clear out old args for (i=0; i<15; i++){argarr[i] = 0;} // get args for this connector - buildPipedArguments(p[(long long unsigned)iter->first], (char **)&argarr, capabilities); + buildPipedArguments(*runningConns.begin(), (char **)&argarr, capabilities); // start piped w/ generated args - Util::Procs::StartPiped(toConn(iter->first), argarr, &zero, &out, &err);//redirects output to out. Must make a new pipe, redirect std err + currentConnectors[*runningConns.begin()] = Util::Procs::StartPiped(argarr, &zero, &out, &err); } + runningConns.erase(runningConns.begin()); } - - //store new state - currentConnectors = new_connectors; } } +