Alfredo Braunstein wrote:

> This is the forked call queue.
> 
> ForkedCallQueue.[Ch] should go in support/
> 
> Alfredo

Forgot the new files.

Alfredo
/**
 * \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_ ;
}
// -*- 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 <string>

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

Reply via email to