The xforms event loop in my tree now looks like:

    while (!finished) {
        ForkedcallsController::get().handleCompletedProcesses();
        if (fl_check_forms() == FL_EVENT) {
            ...
        }
    }

where handleCompletedProcesses() simply checks whether a SIGCHLD 
signal has been received and, if so, cleans up after it. 
(handle_children is set to true in the handler receiving a SIGCHLD 
signal.)

void ForkedcallsController::handleCompletedProcesses()
{
    // The loop ensures that we handle any signals that are 
    // received whilst we're processing an existing signal.
    while (handle_children) {
        handle_children = false;
        wait(); // The old ForkedcallsController::timer() function.
    }
}

Questions:
1. Is this the right way to go?
2. How do I do this for Qt, given that the xforms event loop above is 
replaced with

    qApp->exec();

????

-- 
Angus
? src/frontends/controllers/TODO
? src/frontends/xforms/1.4-XFormsView.C
? src/frontends/xforms/1.4-XWorkArea.C
? src/frontends/xforms/1.4-XWorkArea.h
? src/frontends/xforms/1.4-bmtable.c
? src/frontends/xforms/1.4-bmtable.h
? src/support/lyxlib-orig.C
? src/support/lyxlib.C
Index: src/frontends/xforms/lyx_gui.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/lyx_gui.C,v
retrieving revision 1.58
diff -u -p -r1.58 lyx_gui.C
--- src/frontends/xforms/lyx_gui.C	14 Dec 2003 16:33:56 -0000	1.58
+++ src/frontends/xforms/lyx_gui.C	22 Mar 2004 14:43:53 -0000
@@ -34,6 +34,7 @@
 #include "graphics/LoaderQueue.h"
 
 #include "support/filetools.h"
+#include "support/forkedcontr.h"
 #include "support/lyxlib.h"
 #include "support/os.h"
 #include "support/path_defines.h"
@@ -48,6 +49,7 @@
 
 using lyx::support::AddName;
 using lyx::support::user_lyxdir;
+using lyx::support::ForkedcallsController;
 
 namespace os = lyx::support::os;
 
@@ -308,6 +310,7 @@ void start(string const & batch, vector<
 
 	// enter the event loop
 	while (!finished) {
+		ForkedcallsController::get().handleCompletedProcesses();
 		if (fl_check_forms() == FL_EVENT) {
 			XEvent ev;
 			fl_XNextEvent(&ev);
Index: src/support/forkedcontr.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcontr.C,v
retrieving revision 1.18
diff -u -p -r1.18 forkedcontr.C
--- src/support/forkedcontr.C	22 Mar 2004 14:10:20 -0000	1.18
+++ src/support/forkedcontr.C	22 Mar 2004 14:43:53 -0000
@@ -17,25 +17,22 @@
 #include "forkedcontr.h"
 #include "forkedcall.h"
 #include "lyxfunctional.h"
-#include "debug.h"
-
-#include "frontends/Timeout.h"
 
-#include <boost/bind.hpp>
+#include "debug.h"
 
 #include <cerrno>
+#include <csignal>
 #include <cstdlib>
 #include <unistd.h>
 #include <sys/wait.h>
 
 
-using boost::bind;
-
 using std::endl;
 using std::find_if;
 using std::string;
 
 #ifndef CXX_GLOBAL_CSTD
+using std::signal;
 using std::strerror;
 #endif
 
@@ -43,6 +40,18 @@ using std::strerror;
 namespace lyx {
 namespace support {
 
+namespace {
+
+sig_atomic_t handle_children = false;
+
+extern "C"
+void child_handler(int)
+{
+	handle_children = true;
+}
+
+} // namespace anon
+
 // Ensure, that only one controller exists inside process
 ForkedcallsController & ForkedcallsController::get()
 {
@@ -53,10 +62,7 @@ ForkedcallsController & ForkedcallsContr
 
 ForkedcallsController::ForkedcallsController()
 {
-	timeout_ = new Timeout(100, Timeout::ONETIME);
-
-	timeout_->timeout
-		.connect(bind(&ForkedcallsController::timer, this));
+	signal(SIGCHLD, child_handler);
 }
 
 
@@ -70,22 +76,31 @@ ForkedcallsController::~ForkedcallsContr
 		delete *it;
 	}
 
-	delete timeout_;
+	// Deinstall the signal handler
+	signal(SIGCHLD, SIG_DFL);
 }
 
 
-void ForkedcallsController::addCall(ForkedProcess const & newcall)
+void ForkedcallsController::handleCompletedProcesses()
 {
-	if (!timeout_->running())
-		timeout_->start();
+	// The loop ensures that we handle any signals that are received whilst
+	// we're processing an existing signal.
+	while (handle_children) {
+		handle_children = false;
+		wait();
+	}
+}
 
+
+void ForkedcallsController::addCall(ForkedProcess const & newcall)
+{
 	forkedCalls.push_back(newcall.clone().release());
 }
 
 
 // Timer-call
 // Check the list and, if there is a stopped child, emit the signal.
-void ForkedcallsController::timer()
+void ForkedcallsController::wait()
 {
 	ListType::iterator it  = forkedCalls.begin();
 	ListType::iterator end = forkedCalls.end();
@@ -147,10 +162,6 @@ void ForkedcallsController::timer()
 			++it;
 		}
 	}
-
-	if (!forkedCalls.empty() && !timeout_->running()) {
-		timeout_->start();
-	}
 }
 
 
@@ -167,10 +178,6 @@ void ForkedcallsController::kill(pid_t p
 
 	(*it)->kill(tolerance);
 	forkedCalls.erase(it);
-
-	if (forkedCalls.empty()) {
-		timeout_->stop();
-	}
 }
 
 } // namespace support
Index: src/support/forkedcontr.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/support/forkedcontr.h,v
retrieving revision 1.14
diff -u -p -r1.14 forkedcontr.h
--- src/support/forkedcontr.h	22 Mar 2004 14:10:20 -0000	1.14
+++ src/support/forkedcontr.h	22 Mar 2004 14:43:53 -0000
@@ -20,8 +20,6 @@
 
 #include <list>
 
-class Timeout;
-
 namespace lyx {
 namespace support {
 
@@ -32,6 +30,11 @@ public:
 	/// Get hold of the only controller that can exist inside the process.
 	static ForkedcallsController & get();
 
+	/** Invoked from the GUI process loop to handle any child processes
+	 *  that have been signaled as completed.
+	 */
+    	void handleCompletedProcesses();
+
 	/// Add a new child process to the list of controlled processes.
 	void addCall(ForkedProcess const &);
 
@@ -46,22 +49,16 @@ private:
 	ForkedcallsController(ForkedcallsController const &);
 	~ForkedcallsController();
 
-	/** This method is connected to the timer. Every XX ms it is called
-	 *  so that we can check on the status of the children. Those that
-	 *  are found to have finished are removed from the list and their
-	 *  callback function is passed the final return state.
+	/** 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 timer();
+	void wait();
 
 	/// The child processes
 	typedef std::list<ForkedProcess *> ListType;
 	///
 	ListType forkedCalls;
-
-	/** The timer. Enables us to check the status of the children
-	 *  every XX ms and to invoke a callback on completion.
-	 */
-	Timeout * timeout_;
 };
 
 } // namespace support

Reply via email to