//------------------------------------------------------------------------------
//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/**
 * @file ProcessQueue.h
 * @author Ralf Gerstenberger
 * @date created at 2002/03/25
 * @brief Declaration of odemx::synchronization::ProcessQueue
 * @sa ProcessQueue.cpp
 * @since 1.0
 */

#ifndef ODEMX_SYNC_PROCESSQUEUE_INCLUDED
#define ODEMX_SYNC_PROCESSQUEUE_INCLUDED

#include <odemx/base/TypeDefs.h>

namespace odemx {

// forward declaration
namespace base {
class Process;
}

namespace synchronization {

/** \class ProcessQueue

	\ingroup base

	\author Ralf Gerstenberger

	\brief ProcessQueue is used for process synchronization

	ProcessQueue is a general tool for storing Process objects. It is used
	by synchronization objects. Every Process can stay in no more than one
	ProcessQueue at a time (provisional). If the queue priority of a
	Process in a ProcessQueue is changed, the ProcessQueue is updated.

	\since 1.0
*/
class ProcessQueue
{
public:
	typedef base::ProcessList::size_type SizeType;

	/// Constructor
	ProcessQueue();
	/// Destructor
	virtual ~ProcessQueue();

	/* \name Queue access and information methods
	 * @{
	 */
	/// check if the queue is empty
	bool isEmpty() const;
	/// get pointer to the first process in the queue
	base::Process* getTop() const;
	/// get a reference to the list object representing the queue
	const base::ProcessList& getList() const;
	/// get the current queue length, i.e. number of stored processes
	SizeType getLength() const;
	/**
	 * \brief
	 * 		get the queue position of a specific process
	 * \param p
	 * 		Process pointer to be found in queue
	 * \return
	 *		Position of \p p, or 0 when not found
	 * \note
	 * 		The first queue position is \c 1. \c 0 is reserved for errors.
	 */
	SizeType getPosition( base::Process* p ) const;
	//@}

	/* \name Queue manipulation methods
	 * @{
	 */
	/// remove the first Process from the queue
	virtual void popQueue();
	/// remove a specific Process \p p from the queue
	virtual void remove( base::Process* p );
	/// add Process \p p to the queue, considering order and priority
	virtual void inSort( base::Process* p,  bool fifo = true );
	//@}

protected:
	/// list of Process pointers representing the queue
	base::ProcessList processes_;
	/// size counter for efficiency to avoid calling list::size()
	SizeType length_;
};

/**
 * @brief Awakes, i.e. schedules, all Process objects in queue \p q
 */
extern void awakeAll( ProcessQueue* q );

/**
 * @brief Awakes, i.e. schedules, the first Process object in queue \p q
 */
extern void awakeFirst( ProcessQueue* q );

/**
 * @brief Awakes, i.e. schedules, the Process object that comes after \p p in queue \p q
 */
extern void awakeNext( ProcessQueue* q, base::Process* p );

} } // namespace odemx::synchronization

#endif /* ODEMX_SYNC_PROCESSQUEUE_INCLUDED */
