X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FForkedCalls.h;h=8a4bf1d4aa40a9cc53a4e904fd73ff464eab4cbc;hb=41a8994da902031a743373c1c57d028b7c900797;hp=7d26bf42f3202c10dae128e8240c92a049457954;hpb=1aafa6ff77b792e4ddc3454d9604bf9c15588731;p=lyx.git diff --git a/src/support/ForkedCalls.h b/src/support/ForkedCalls.h index 7d26bf42f3..8a4bf1d4aa 100644 --- a/src/support/ForkedCalls.h +++ b/src/support/ForkedCalls.h @@ -14,18 +14,14 @@ #ifndef FORKEDCALLS_H #define FORKEDCALLS_H -#include -#include +#include "support/signals.h" +#include "support/strfwd.h" #ifdef HAVE_SYS_TYPES_H # include #endif -#include -#include -#include -#include -#include +#include namespace lyx { @@ -46,9 +42,9 @@ public: /// virtual ~ForkedProcess() {} /// - virtual boost::shared_ptr clone() const = 0; + virtual std::shared_ptr clone() const = 0; - /** A SignalType signal is can be emitted once the forked process + /** A Signal signal can be emitted once the forked process * has finished. It passes: * the PID of the child and; * the return value from the child. @@ -57,7 +53,8 @@ public: * we can return easily to C++ methods, rather than just globally * accessible functions. */ - typedef boost::signal SignalType; + typedef signals2::signal sig; + typedef sig::slot_type slot; /** The signal is connected in the calling routine to the desired * slot. We pass a shared_ptr rather than a reference to the signal @@ -65,9 +62,10 @@ public: * class (and hence the signal) to be destructed before the forked * call is complete. * - * It doesn't matter if the slot disappears, SigC takes care of that. + * Use Slot::track or Signal::scoped_connection to ensure that the + * connection is closed before the slot expires. */ - typedef boost::shared_ptr SignalTypePtr; + typedef std::shared_ptr sigPtr; /** Invoking the following methods makes sense only if the command * is running asynchronously! @@ -102,14 +100,23 @@ public: */ 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_; + sigPtr signal_; /// identifying command (for display in the GUI perhaps). std::string command_; @@ -123,12 +130,15 @@ private: /// 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. @@ -144,13 +154,17 @@ private: class ForkedCall : public ForkedProcess { public: /// - virtual boost::shared_ptr clone() const { - return boost::shared_ptr(new ForkedCall(*this)); + ForkedCall(std::string const & path = empty_string(), + std::string const & lpath = empty_string()); + /// + virtual std::shared_ptr clone() const { + return std::make_shared(*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 @@ -163,96 +177,55 @@ public: int startScript(Starttype, std::string const & what); /// - int startScript(std::string const & what, SignalTypePtr); + int startScript(std::string const & what, sigPtr ptr); 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 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 callQueue_; - /// - bool running_; - /// - void callNext(); - /// - void startCaller(); - /// - void stopCaller(); - /// - void callback(pid_t, int); -}; +ForkedCall::sigPtr add(std::string const & process); +/// Query whether the queue is running a forked process now. +bool running(); + +} // namespace ForkedCallQueue /** - * 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 &); - - /** 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(); - - /** 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); +namespace ForkedCallsController { -private: - ForkedCallsController(); - ForkedCallsController(ForkedCallsController const &); - ~ForkedCallsController(); +/// Add a new child process to the list of controlled processes. +void addCall(ForkedProcess const &); - typedef boost::shared_ptr ForkedProcessPtr; - typedef std::list 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)