]> git.lyx.org Git - lyx.git/blobdiff - src/support/forkedcontr.C
split LyXText::rowlist_ into individual Paragraph::rows_ chunks
[lyx.git] / src / support / forkedcontr.C
index 13b397eb8887c5881fac7a27c0b70f38f62919bf..c11daa5669c24d82cee2ab9d88c22f8ef7f596d9 100644 (file)
@@ -1,27 +1,28 @@
 /**
  * \file forkedcontr.C
- * Copyright 2001 The LyX Team
- * Read COPYING
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup Nielsen
  * \author Angus Leeming
  *
- * A class for the control of child processes launched using 
+ * Full author contact details are available in file CREDITS
+ *
+ * A class for the control of child processes launched using
  * fork() and execvp().
  */
 
 #include <config.h>
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include "forkedcontr.h"
 #include "forkedcall.h"
 #include "lyxfunctional.h"
-#include "frontends/Timeout.h"
 #include "debug.h"
 
+#include "frontends/Timeout.h"
+
+#include <boost/bind.hpp>
+
 #include <cerrno>
 #include <cstdlib>
 #include <unistd.h>
@@ -35,6 +36,9 @@ using std::find_if;
 using std::strerror;
 #endif
 
+namespace lyx {
+namespace support {
+
 // Ensure, that only one controller exists inside process
 ForkedcallsController & ForkedcallsController::get()
 {
@@ -45,10 +49,10 @@ ForkedcallsController & ForkedcallsController::get()
 
 ForkedcallsController::ForkedcallsController()
 {
-       timeout_ = new Timeout(100, Timeout::CONTINUOUS);
-       
+       timeout_ = new Timeout(100, Timeout::ONETIME);
+
        timeout_->timeout
-               .connect(SigC::slot(this, &ForkedcallsController::timer));
+               .connect(boost::bind(&ForkedcallsController::timer, this));
 }
 
 
@@ -66,15 +70,13 @@ ForkedcallsController::~ForkedcallsController()
 }
 
 
-// Add child process information to the list of controlled processes
-void ForkedcallsController::addCall(Forkedcall const &newcall)
+void ForkedcallsController::addCall(ForkedProcess const & newcall)
 {
        if (!timeout_->running())
                timeout_->start();
 
-       Forkedcall * call = new Forkedcall(newcall);
-       forkedCalls.push_back(call);
-       childrenChanged.emit();
+       forkedCalls.push_back(newcall.clone());
+       childrenChanged();
 }
 
 
@@ -84,9 +86,10 @@ void ForkedcallsController::timer()
 {
        ListType::size_type start_size = forkedCalls.size();
 
-       for (ListType::iterator it = forkedCalls.begin();
-            it != forkedCalls.end(); ++it) {
-               Forkedcall * actCall = *it;
+       ListType::iterator it  = forkedCalls.begin();
+       ListType::iterator end = forkedCalls.end();
+       while (it != end) {
+               ForkedProcess * actCall = *it;
 
                pid_t pid = actCall->pid();
                int stat_loc;
@@ -94,7 +97,7 @@ void ForkedcallsController::timer()
                bool remove_it = false;
 
                if (waitrpid == -1) {
-                       lyxerr << "LyX: Error waiting for child: " 
+                       lyxerr << "LyX: Error waiting for child: "
                               << strerror(errno) << endl;
 
                        // Child died, so pretend it returned 1
@@ -103,7 +106,6 @@ void ForkedcallsController::timer()
 
                } else if (waitrpid == 0) {
                        // Still running. Move on to the next child.
-                       continue;
 
                } else if (WIFEXITED(stat_loc)) {
                        // Ok, the return value goes into retval.
@@ -116,9 +118,9 @@ void ForkedcallsController::timer()
                        remove_it = true;
 
                } else if (WIFSTOPPED(stat_loc)) {
-                       lyxerr << "LyX: Child (pid: " << pid 
+                       lyxerr << "LyX: Child (pid: " << pid
                               << ") stopped on signal "
-                              << WSTOPSIG(stat_loc) 
+                              << WSTOPSIG(stat_loc)
                               << ". Waiting for child to finish." << endl;
 
                } else {
@@ -131,24 +133,26 @@ void ForkedcallsController::timer()
                }
 
                if (remove_it) {
-                       // Emit signal and remove the item from the list
+                       forkedCalls.erase(it);
+
                        actCall->emitSignal();
                        delete actCall;
-                       // erase returns the next iterator, so decrement it
-                       // to continue the loop.
-                       ListType::iterator prev = it;
-                       --prev;
-                       forkedCalls.erase(it);
-                       it = prev;
+
+                       /* start all over: emiting the signal can result
+                        * in changing the list (Ab)
+                        */
+                       it = forkedCalls.begin();
+               } else {
+                       ++it;
                }
        }
 
-       if (forkedCalls.empty()) {
-               timeout_->stop();
+       if (!forkedCalls.empty() && !timeout_->running()) {
+               timeout_->start();
        }
 
        if (start_size != forkedCalls.size())
-               childrenChanged.emit();
+               childrenChanged();
 }
 
 
@@ -205,3 +209,6 @@ void ForkedcallsController::kill(pid_t pid, int tolerance)
                timeout_->stop();
        }
 }
+
+} // namespace support
+} // namespace lyx