#ifndef FORKEDCALLS_H
#define FORKEDCALLS_H
-#include <boost/shared_ptr.hpp>
+#include "support/shared_ptr.h"
+#include "support/strfwd.h"
#include <boost/signal.hpp>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#include <list>
-#include <queue>
-#include <string>
-#include <utility>
-#include <vector>
-
-
namespace lyx {
namespace support {
///
virtual ~ForkedProcess() {}
///
- virtual boost::shared_ptr<ForkedProcess> clone() const = 0;
+ virtual shared_ptr<ForkedProcess> clone() const = 0;
- /** A SignalType signal is can be emitted once the forked process
+ /** A SignalType signal can be emitted once the forked process
* has finished. It passes:
* the PID of the child and;
* the return value from the child.
*
* It doesn't matter if the slot disappears, SigC takes care of that.
*/
- typedef boost::shared_ptr<SignalType> SignalTypePtr;
+ typedef shared_ptr<SignalType> SignalTypePtr;
/** Invoking the following methods makes sense only if the command
* is running asynchronously!
*/
void kill(int tolerance = 5);
+ /// Returns true if this is a child process
+ static bool iAmAChild() { return IAmAChild; }
+
protected:
/** Spawn the child process.
* Returns returncode from child.
*/
int run(Starttype type);
+ /// implement our own version of fork()
+ /// it just returns -1 if ::fork() is not defined
+ /// otherwise, it forks and sets the global child-process
+ /// boolean IAmAChild
+ pid_t fork();
+
/// Callback function
SignalTypePtr signal_;
/// generate child in background
virtual int generateChild() = 0;
+ ///
+ static bool IAmAChild;
+
/// Wait for child process to finish. Updates returncode from child.
int waitForChild();
};
-/*
+/**
* An instance of class ForkedCall represents a single child process.
*
* Class ForkedCall uses fork() and execvp() to lauch the child process.
class ForkedCall : public ForkedProcess {
public:
///
- virtual boost::shared_ptr<ForkedProcess> clone() const {
- return boost::shared_ptr<ForkedProcess>(new ForkedCall(*this));
+ ForkedCall(std::string const & path = empty_string());
+ ///
+ virtual shared_ptr<ForkedProcess> clone() const {
+ return shared_ptr<ForkedProcess>(new ForkedCall(*this));
}
/** Start the child process.
*
- * The command "what" is passed to execvp() for execution.
+ * The command "what" is passed to execvp() for execution. "$$s" is
+ * replaced accordingly by commandPrep().
*
* There are two startScript commands available. They differ in that
* the second receives a signal that is executed on completion of
private:
///
virtual int generateChild();
+ ///
+ std::string cmd_prefix_;
};
/**
- * This class implements a queue of forked processes. In order not to
+ * This interfaces a queue of forked processes. In order not to
* hose the system with multiple processes running simultaneously, you can
* request the addition of your process to this queue and it will be
* executed when its turn comes.
*
*/
-class ForkedCallQueue {
-public:
- /// A process in the queue
- typedef std::pair<std::string, ForkedCall::SignalTypePtr> Process;
- /** Add a process to the queue. Processes are forked sequentially
- * only one is running at a time.
- * Connect to the returned signal and you'll be informed when
- * the process has ended.
- */
- ForkedCall::SignalTypePtr add(std::string const & process);
- /// Query whether the queue is running a forked process now.
- bool running() const;
- /// Get the and only instance of the class
- static ForkedCallQueue & get();
+namespace ForkedCallQueue {
-private:
- /** this class is a singleton class... use
- * ForkedCallQueue::get() instead
- */
- ForkedCallQueue();
- /// in-progress queue
- std::queue<Process> callQueue_;
- ///
- bool running_;
- ///
- void callNext();
- ///
- void startCaller();
- ///
- void stopCaller();
- ///
- void callback(pid_t, int);
-};
+ForkedCall::SignalTypePtr add(std::string const & process);
+/// Query whether the queue is running a forked process now.
+bool running();
+
+}
/**
- * A class for the control of child processes launched using
- * fork() and execvp().
+ * Control of child processes launched using fork() and execvp().
*/
-class ForkedCallsController {
-public:
- /// Get hold of the only controller that can exist inside the process.
- static ForkedCallsController & get();
-
- /// Add a new child process to the list of controlled processes.
- void addCall(ForkedProcess const &);
+namespace ForkedCallsController {
- /** Those child processes that are found to have finished are removed
- * from the list and their callback function is passed the final
- * return state.
- */
- void handleCompletedProcesses();
+/// Add a new child process to the list of controlled processes.
+void addCall(ForkedProcess const &);
- /** Kill this process prematurely and remove it from the list.
- * The process is killed within tolerance secs.
- * See forkedcall.[Ch] for details.
- */
- void kill(pid_t, int tolerance = 5);
-
-private:
- ForkedCallsController();
- ForkedCallsController(ForkedCallsController const &);
- ~ForkedCallsController();
-
- typedef boost::shared_ptr<ForkedProcess> ForkedProcessPtr;
- typedef std::list<ForkedProcessPtr> ListType;
- typedef ListType::iterator iterator;
+/** Those child processes that are found to have finished are removed
+ * from the list and their callback function is passed the final
+ * return state.
+ */
+void handleCompletedProcesses();
- iterator find_pid(pid_t);
+/** Kill this process prematurely and remove it from the list.
+ * The process is killed within tolerance secs.
+ * See forkedcall.[Ch] for details.
+ */
+void kill(pid_t, int tolerance = 5);
- /// The child processes
- ListType forkedCalls;
-};
+} // namespace ForkedCallsController
#if defined(_WIN32)