Alfredo's forkedcall queue.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6267 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2003-02-25 18:56:09 +00:00
parent dc75a0e178
commit 3ac369b71c
5 changed files with 162 additions and 12 deletions

View File

@ -17,6 +17,7 @@
#include "support/filetools.h"
#include "support/forkedcall.h"
#include "support/forkedcallqueue.h"
#include "support/lyxlib.h"
#include <boost/bind.hpp>
@ -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_)

View File

@ -1,3 +1,7 @@
2003-02-25 Alfredo Braunstein <abraunst@libero.it>
* forkedcallqueue.[Ch]: added
2003-02-25 Alfredo Braunstein <abraunst@libero.it>
* forkedcontr.C (timer): Start the loop afresh if an item is deleted.

View File

@ -32,6 +32,8 @@ libsupport_la_SOURCES = \
filetools.h \
forkedcall.C \
forkedcall.h \
forkedcallqueue.C \
forkedcallqueue.h \
forkedcontr.C \
forkedcontr.h \
getcwd.C \

View File

@ -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 <boost/bind.hpp>
#include <boost/signals/signal2.hpp>
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_ ;
}

View File

@ -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 <queue>
#include <utility>
#include "LString.h"
class ForkedCallQueue {
public:
/// A process in the queue
typedef std::pair<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(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<Process> callQueue_;
///
bool running_;
///
void callNext();
///
void startCaller();
///
void stopCaller();
///
void callback(pid_t, int);
};
#endif // FORKEDCALLQUEUE_H