From: Christian P. <cp...@us...> - 2005-02-22 13:22:10
|
Update of /cvsroot/pclasses/pclasses2/src/System In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24363/src/System Modified Files: Process.posix.cpp Log Message: Added ProcessListener Index: Process.posix.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/System/Process.posix.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Process.posix.cpp 31 Dec 2004 03:22:57 -0000 1.1 +++ Process.posix.cpp 22 Feb 2005 13:21:49 -0000 1.2 @@ -31,11 +31,80 @@ #include <errno.h> #include <string> +#include <list> + +#include "../System/FdListener.h" +#include "../System/SignalListener.h" namespace P { namespace System { +class ChildSignalHandler: public System::SignalListener { + public: + ChildSignalHandler() + : SignalListener(SIGCHLD) { } + + void onSignal() + { + ProcessListener* proc = 0; + int exitCode = 0; + + std::list<ProcessListener*>::iterator i = _procs.begin(); + while(i != _procs.end()) + { + proc = *i; + if(proc->process().tryWait(exitCode)) + { + // we post this Event since signals are always handled by the + // main-thread, and the EventListener may use a EventQueue + // that runs in another thread... + proc->eventQueue().post(Event(proc->sender(), exitCode)); + } + + ++i; + } + } + + void add(ProcessListener* proc) + { + _procs.push_back(proc); + } + + void remove(ProcessListener* proc) + { + std::list<ProcessListener*>::iterator i = _procs.begin(); + while(i != _procs.end()) + { + if(*i == proc) + { + _procs.erase(i); + break; + } + + ++i; + } + } + + static ChildSignalHandler& instance() + { + if(!_instance) + { + static CriticalSection cs; + CriticalSection::ScopedLock lck(cs); + _instance = new ChildSignalHandler(); + } + + return *_instance; + } + + private: + std::list<ProcessListener*> _procs; + static ChildSignalHandler* _instance; +}; + +ChildSignalHandler* ChildSignalHandler::_instance = 0; + void Process::start(int mode) throw(IO::IOError,SystemError,LogicError) { @@ -83,15 +152,16 @@ throw IO::IOError(errno, "Could not create pipe", P_SOURCEINFO); } } - + pid_t child = fork(); - + // fork failed if(child == -1) { close(infds[0]); close(infds[1]); close(outfds[0]); close(outfds[1]); close(errfds[0]); close(errfds[1]); + throw SystemError(errno, "Could not start process", P_SOURCEINFO); } // child process @@ -244,6 +314,36 @@ return WIFEXITED(status) ? WEXITSTATUS(status) : 127; } +ProcessListener::ProcessListener(Process& proc) +: EventListener(&proc), _proc(proc) +{ + ChildSignalHandler& childSigHandler = ChildSignalHandler::instance(); + childSigHandler.add(this); +} + +ProcessListener::ProcessListener(EventQueue& evq, Process& proc) +: EventListener(evq, &proc), _proc(proc) +{ + ChildSignalHandler& childSigHandler = ChildSignalHandler::instance(); + childSigHandler.add(this); +} + +ProcessListener::~ProcessListener() +{ + ChildSignalHandler& childSigHandler = ChildSignalHandler::instance(); + childSigHandler.remove(this); +} + +Process& ProcessListener::process() const throw() +{ + return _proc; +} + +void ProcessListener::signaled(const Event& ev) +{ + sigExited.fire(*this, ev.id()); +} + } // !namespace System } // !namespace P |