From 3ac369b71c310df991444de93d1bd3e5846057d5 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Tue, 25 Feb 2003 18:56:09 +0000 Subject: [PATCH] Alfredo's forkedcall queue. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6267 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/graphics/GraphicsConverter.C | 16 ++---- src/support/ChangeLog | 4 ++ src/support/Makefile.am | 2 + src/support/forkedcallqueue.C | 90 ++++++++++++++++++++++++++++++++ src/support/forkedcallqueue.h | 62 ++++++++++++++++++++++ 5 files changed, 162 insertions(+), 12 deletions(-) create mode 100644 src/support/forkedcallqueue.C create mode 100644 src/support/forkedcallqueue.h diff --git a/src/graphics/GraphicsConverter.C b/src/graphics/GraphicsConverter.C index 0bb7cd7054..5db2442feb 100644 --- a/src/graphics/GraphicsConverter.C +++ b/src/graphics/GraphicsConverter.C @@ -17,6 +17,7 @@ #include "support/filetools.h" #include "support/forkedcall.h" +#include "support/forkedcallqueue.h" #include "support/lyxlib.h" #include @@ -191,22 +192,13 @@ void Converter::Impl::startConversion() return; } - // Initiate the conversion - Forkedcall::SignalTypePtr convert_ptr; - convert_ptr.reset(new Forkedcall::SignalType); + Forkedcall::SignalTypePtr + ptr = ForkedCallQueue::get().add(script_command_); - convert_ptr->connect( - boost::bind(&Impl::converted, this, _1, _2)); + ptr->connect(boost::bind(&Impl::converted, this, _1, _2)); - Forkedcall call; - int retval = call.startscript(script_command_, convert_ptr); - if (retval > 0) { - // Unable to even start the script, so clean-up the mess! - converted(0, 1); - } } - void Converter::Impl::converted(pid_t /* pid */, int retval) { if (finished_) diff --git a/src/support/ChangeLog b/src/support/ChangeLog index 8ee4185788..2af1f28874 100644 --- a/src/support/ChangeLog +++ b/src/support/ChangeLog @@ -1,3 +1,7 @@ +2003-02-25 Alfredo Braunstein + + * forkedcallqueue.[Ch]: added + 2003-02-25 Alfredo Braunstein * forkedcontr.C (timer): Start the loop afresh if an item is deleted. diff --git a/src/support/Makefile.am b/src/support/Makefile.am index dc457d4748..398e582870 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -32,6 +32,8 @@ libsupport_la_SOURCES = \ filetools.h \ forkedcall.C \ forkedcall.h \ + forkedcallqueue.C \ + forkedcallqueue.h \ forkedcontr.C \ forkedcontr.h \ getcwd.C \ diff --git a/src/support/forkedcallqueue.C b/src/support/forkedcallqueue.C new file mode 100644 index 0000000000..378de1af5c --- /dev/null +++ b/src/support/forkedcallqueue.C @@ -0,0 +1,90 @@ +/** + * \file forkedcallqueue.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Alfredo Braunstein (based on an idea from Angus Leeming) + * + * Full author contact details are available in file CREDITS + */ + +#include "forkedcallqueue.h" + +#include "debug.h" + +#include +#include + +using std::endl; +using std::queue; + +ForkedCallQueue & ForkedCallQueue::get() +{ + static ForkedCallQueue singleton; + return singleton; +} + + +Forkedcall::SignalTypePtr ForkedCallQueue::add(string const & process) +{ + Forkedcall::SignalTypePtr ptr; + ptr.reset(new Forkedcall::SignalType); + callQueue_.push(Process(process, ptr)); + if (!running_) { + startCaller(); + } + return ptr; +} + + +void ForkedCallQueue::callNext() +{ + if (callQueue_.empty()) + return; + Process pro = callQueue_.front(); + callQueue_.pop(); + // Bind our chain caller + pro.second->connect(boost::bind(&ForkedCallQueue::callback, + this, _1, _2)); + Forkedcall call; + // If we fail to fork the process, then emit the signal + // to tell the outside world that it failed. + if (call.startscript(pro.first, pro.second) > 0) { + pro.second->operator()(0,1); + } +} + + +void ForkedCallQueue::callback(pid_t, int) +{ + if(callQueue_.empty()) { + stopCaller(); + } else { + callNext(); + } +} + +ForkedCallQueue::ForkedCallQueue() : running_(false) +{} + + +void ForkedCallQueue::startCaller() +{ + lyxerr[Debug::GRAPHICS] << "ForkedCallQueue: waking up" << endl; + running_ = true ; + callNext(); +} + + +void ForkedCallQueue::stopCaller() +{ + running_ = false ; + lyxerr[Debug::GRAPHICS] << "ForkedCallQueue: I'm going to sleep" + << endl; +} + + +bool ForkedCallQueue::running() const +{ + return running_ ; +} diff --git a/src/support/forkedcallqueue.h b/src/support/forkedcallqueue.h new file mode 100644 index 0000000000..817d7bb873 --- /dev/null +++ b/src/support/forkedcallqueue.h @@ -0,0 +1,62 @@ +// -*- C++ -*- +/** + * \file forkedcallqueue.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Alfredo Braunstein (based on an idea from Angus Leeming) + * + * Full author contact details are available in file CREDITS + * + * This class implements 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. + * + */ + +#ifndef FORKEDCALLQUEUE_H +#define FORKEDCALLQUEUE_H + +#include "forkedcall.h" + +#include +#include +#include "LString.h" + +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(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(); + +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); +}; + +#endif // FORKEDCALLQUEUE_H -- 2.39.5