]> granicus.if.org Git - icinga2/commitdiff
ExternalCommandListener: Use threads per client connection
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 5 Aug 2014 16:01:01 +0000 (18:01 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Tue, 5 Aug 2014 16:01:01 +0000 (18:01 +0200)
fixes #6589

components/compat/externalcommandlistener.cpp
components/compat/externalcommandlistener.hpp

index 437cf6943ed2ef4b00e895c5b3df53498e132135..a89d3280322823c231e25921cbed1a901718faa3 100644 (file)
@@ -99,50 +99,63 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath)
        for (;;) {
                int fd;
 
-               do {
-                       fd = open(commandPath.CStr(), O_RDONLY);
-               } while (fd < 0 && errno == EINTR);
-
-               if (fd < 0) {
-                       std::ostringstream msgbuf;
-                       msgbuf << "open() for fifo path '" << commandPath << "'failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
-                       Log(LogCritical, "ExternalCommandListener",  msgbuf.str());
-                       return;
-               }
+               try {
+                       do {
+                               fd = open(commandPath.CStr(), O_RDONLY);
+                       } while (fd < 0 && errno == EINTR);
+
+                       if (fd < 0) {
+                               std::ostringstream msgbuf;
+                               msgbuf << "open() for fifo path '" << commandPath << "'failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
+                               Log(LogCritical, "ExternalCommandListener",  msgbuf.str());
+                               return;
+                       }
+
 
-               FILE *fp = fdopen(fd, "r");
 
-               if (fp == NULL) {
-                       std::ostringstream msgbuf;
-                       msgbuf << "fdopen() for fifo path '" << commandPath << "'failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
-                       Log(LogCritical, "ExternalCommandListener",  msgbuf.str());
-                       return;
+                       Log(LogNotice, "ExternalCommandListener", "Client connected");
+                       Utility::QueueAsyncCallback(boost::bind(&ExternalCommandListener::ClientHandler, this, commandPath, fd));
+               } catch (std::exception&) {
+                       Log(LogCritical, "ExternalCommandListener", "Cannot accept new connection.");
                }
+       }
+}
 
-               const int linesize = 128 * 1024;
-               char *line = new char[linesize];
+void ExternalCommandListener::ClientHandler(const String& commandPath, int fd)
+{
+       FILE *fp = fdopen(fd, "r");
+
+       if (fp == NULL) {
+               std::ostringstream msgbuf;
+               msgbuf << "fdopen() for fifo path '" << commandPath << "'failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
+               Log(LogCritical, "ExternalCommandListener",  msgbuf.str());
+               return;
+       }
 
-               while (fgets(line, linesize, fp) != NULL) {
-                       // remove trailing new-line
-                       while (strlen(line) > 0 &&
-                           (line[strlen(line) - 1] == '\r' || line[strlen(line) - 1] == '\n'))
-                               line[strlen(line) - 1] = '\0';
+       const int linesize = 128 * 1024;
+       char *line = new char[linesize];
 
-                       String command = line;
+       while (fgets(line, linesize, fp) != NULL) {
+               // remove trailing new-line
+               while (strlen(line) > 0 &&
+                   (line[strlen(line) - 1] == '\r' || line[strlen(line) - 1] == '\n'))
+                       line[strlen(line) - 1] = '\0';
+       }
 
-                       try {
-                               Log(LogInformation, "ExternalCommandListener", "Executing external command: " + command);
+       String command = line;
 
-                               ExternalCommandProcessor::Execute(command);
-                       } catch (const std::exception&) {
-                               std::ostringstream msgbuf;
-                               msgbuf << "External command failed.";
-                               Log(LogWarning, "ExternalCommandListener", msgbuf.str());
-                       }
-               }
+       try {
+               Log(LogInformation, "ExternalCommandListener", "Executing external command: " + command);
 
-               delete line;
-               fclose(fp);
+               ExternalCommandProcessor::Execute(command);
+       } catch (const std::exception&) {
+               std::ostringstream msgbuf;
+               msgbuf << "External command failed.";
+               Log(LogWarning, "ExternalCommandListener", msgbuf.str());
+               return;
        }
+
+       delete line;
+       fclose(fp);
 }
 #endif /* _WIN32 */
index 665b0272aea44749dbcd409f28af7a9800f6e295..db65fadb2e2b0c6656df65568b7dc65bce814211 100644 (file)
@@ -49,6 +49,7 @@ private:
        boost::thread m_CommandThread;
 
        void CommandPipeThread(const String& commandPath);
+        void ClientHandler(const String& commandPath, int fd);
 #endif /* _WIN32 */
 };