]> granicus.if.org Git - icinga2/commitdiff
Fix command timeout.
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 19 May 2014 11:09:26 +0000 (13:09 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 19 May 2014 11:09:49 +0000 (13:09 +0200)
Fixes #6232

lib/base/process.cpp
lib/icinga/command.ti

index d6366324df9b3193fe8e9c8b606b5a1ce6aa6e50..c4d5eb5f0afc90715d1a069822e80cc56713b684 100644 (file)
@@ -155,11 +155,12 @@ void Process::IOThreadProc(int tid)
        pollfd *pfds = NULL;
 #endif /* _WIN32 */
        int count = 0;
+       double now;
 
        Utility::SetThreadName("ProcessIO");
 
        for (;;) {
-               double now, timeout = -1;
+               double timeout = -1;
 
                now = Utility::GetTime();
 
@@ -202,8 +203,10 @@ void Process::IOThreadProc(int tid)
                        }
                }
 
-               if (timeout != -1)
-                       timeout *= 1000;
+               if (timeout < 0.01)
+                       timeout = 0.5;
+
+               timeout *= 1000;
 
 #ifdef _WIN32
                DWORD rc = WaitForMultipleObjects(count, handles, FALSE, timeout == -1 ? INFINITE : static_cast<DWORD>(timeout));
@@ -214,6 +217,8 @@ void Process::IOThreadProc(int tid)
                        continue;
 #endif /* _WIN32 */
 
+               now = Utility::GetTime();
+
                {
                        boost::mutex::scoped_lock lock(l_ProcessMutex[tid]);
 
@@ -228,27 +233,36 @@ void Process::IOThreadProc(int tid)
 #endif /* _WIN32 */
 
                        for (int i = 1; i < count; i++) {
-#ifdef _WIN32
-                               if (rc == WAIT_OBJECT_0 + i) {
-#else /* _WIN32 */
-                               if (pfds[i].revents & (POLLIN | POLLHUP | POLLERR)) {
-                                       std::map<ConsoleHandle, ProcessHandle>::iterator it2;
-                                       it2 = l_FDs[tid].find(pfds[i].fd);
+                               std::map<ConsoleHandle, ProcessHandle>::iterator it2;
+                               it2 = l_FDs[tid].find(pfds[i].fd);
 
-                                       if (it2 == l_FDs[tid].end())
-                                               continue; /* This should never happen. */
+                               if (it2 == l_FDs[tid].end())
+                                       continue; /* This should never happen. */
 
-#endif /* _WIN32 */
-                                       std::map<ProcessHandle, Process::Ptr>::iterator it;
+                               std::map<ProcessHandle, Process::Ptr>::iterator it;
 #ifdef _WIN32
-                                       it = l_Processes[tid].find(handles[i]);
+                               it = l_Processes[tid].find(handles[i]);
 #else /* _WIN32 */
-                                       it = l_Processes[tid].find(it2->second);
+                               it = l_Processes[tid].find(it2->second);
 #endif /* _WIN32 */
 
-                                       if (it == l_Processes[tid].end())
-                                               continue; /* This should never happen. */
+                               if (it == l_Processes[tid].end())
+                                       continue; /* This should never happen. */
 
+                               bool is_timeout = false;
+
+                               if (it->second->m_Timeout != 0) {
+                                       double timeout = it->second->m_Result.ExecutionStart + it->second->m_Timeout;
+
+                                       if (timeout < now)
+                                               is_timeout = true;
+                               }
+
+#ifdef _WIN32
+                               if (rc == WAIT_OBJECT_0 + i || is_timeout) {
+#else /* _WIN32 */
+                               if (pfds[i].revents & (POLLIN | POLLHUP | POLLERR) || is_timeout) {
+#endif /* _WIN32 */
                                        if (!it->second->DoEvents()) {
 #ifdef _WIN32
                                                CloseHandle(it->first);
@@ -562,42 +576,48 @@ void Process::Run(const boost::function<void(const ProcessResult&)>& callback)
 
 bool Process::DoEvents(void)
 {
+       bool is_timeout = false;
+
        if (m_Timeout != 0) {
-               double timeout = m_Timeout - (Utility::GetTime() - m_Result.ExecutionStart);
+               double timeout = m_Result.ExecutionStart + m_Timeout;
 
-               if (timeout < 0) {
+               if (timeout < Utility::GetTime()) {
                        m_OutputStream << "<Timeout exceeded.>";
 #ifdef _WIN32
                        TerminateProcess(m_Process, 1);
 #else /* _WIN32 */
                        kill(m_Process, SIGKILL);
 #endif /* _WIN32 */
+
+                       is_timeout = true;
                }
        }
 
-       char buffer[512];
-       for (;;) {
+       if (!is_timeout) {
+               char buffer[512];
+               for (;;) {
 #ifdef _WIN32
-               DWORD rc;
-               if (!ReadFile(m_FD, buffer, sizeof(buffer), &rc, NULL) || rc == 0)
-                       break;
+                       DWORD rc;
+                       if (!ReadFile(m_FD, buffer, sizeof(buffer), &rc, NULL) || rc == 0)
+                               break;
 #else /* _WIN32 */
-               int rc = read(m_FD, buffer, sizeof(buffer));
+                       int rc = read(m_FD, buffer, sizeof(buffer));
 
-               if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
-                       return true;
+                       if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
+                               return true;
 
-               if (rc > 0) {
+                       if (rc > 0) {
 #endif /* _WIN32 */
-                       m_OutputStream.write(buffer, rc);
+                               m_OutputStream.write(buffer, rc);
 #ifdef _WIN32
-                       return true;
+                               return true;
 #else /* _WIN32 */
-                       continue;
-               }
+                               continue;
+                       }
 #endif /* _WIN32 */
 
-               break;
+                       break;
+               }
        }
 
        String output = m_OutputStream.str();
index 895533d8672f18ef44200ca864f8d31bfc7924a9..ca6e86244d29484147f4a439edd43d0b1fb23f03 100644 (file)
@@ -8,7 +8,7 @@ abstract class Command : DynamicObject
        [config] Value command (CommandLine);
        [config] Value arguments;
        [config] Value timeout {
-               default {{{ return 300; }}}
+               default {{{ return 60; }}}
        };
        [config] Dictionary::Ptr env;
 };