/**
* \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>
using std::strerror;
#endif
+namespace lyx {
+namespace support {
+
// Ensure, that only one controller exists inside process
ForkedcallsController & ForkedcallsController::get()
{
ForkedcallsController::ForkedcallsController()
{
timeout_ = new Timeout(100, Timeout::ONETIME);
-
+
timeout_->timeout
- .connect(SigC::slot(this, &ForkedcallsController::timer));
+ .connect(boost::bind(&ForkedcallsController::timer, this));
}
}
-// 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();
}
{
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;
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
} 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.
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 {
}
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()) {
+ if (!forkedCalls.empty() && !timeout_->running()) {
timeout_->start();
}
if (start_size != forkedCalls.size())
- childrenChanged.emit();
+ childrenChanged();
}
timeout_->stop();
}
}
+
+} // namespace support
+} // namespace lyx