/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * 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
 *
 * $Id: Queue.h,v 1.15 2002/12/01 10:25:59 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_UTIL_QUEUE_H
# define INCLUDE_JAKELIB2_UTIL_QUEUE_H
# include "../lang/Semaphore.h"

namespace jakelib {
  namespace util {
    class ArrayList;

    /**
     * This class implements a synchronized FIFO (first in, first out)
     * data storage.
     * A <tt>Queue</tt> is created with a constant size. 
     * To avoid dead-locks, <tt>Queue</tt> should be used in multi-threaded
     * applications where one thread puts data into the queue and another
     * one gets data out of the queue.
     * If a program calls <tt>put</tt> on a full queue, the current thread
     * is blocked until the operation can be performed.
     * If a program calls <tt>get</tt> on an empty queue, the thread is
     * blocked until a data object becomes available.
     *
     * @class Queue
     * @version $Id: Queue.h,v 1.15 2002/12/01 10:25:59 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class Queue : public jakelib::lang::Object
      {
      public:
	/**
	 * Creates a new Queue with a given size.
	 *
	 * @param size
	 */
	Queue(int size);

	~Queue();
  
	/**
	 * Enqueues an objects. Thread will be blocked if the queue is full.
	 *
	 * @param obj The object to be queued.
	 */
	void put(jakelib::lang::Object* obj);
  
	/**
	 * Gets the first element from the queue. Thread will be blocked if
	 * the queue is empty.
	 * Don't forget to <tt>UNREF</tt> the object after usage.
	 */
	jakelib::lang::Object* get();

	jboolean isEmpty();

	jboolean isFull();

	/**
	 * Returns the length (= number of occupied OR empty entries) of the queue.
	 */
	int length();

	/**
	 * Returns the number of occupied entries of the queue.
	 */
	int entries();

	/**
	 * Returns a new ArrayList containing pointers to all entries of
	 * the queue.
	 * Don't forget to <tt>delete</tt> the object after usage.
	 */
	ArrayList* extractEntries();

      protected:
	void init();
	jakelib::lang::Semaphore* sync;
	jakelib::lang::Semaphore* readSem;
	jakelib::lang::Semaphore* writeSem;
	int size;
	int count;
	int readIndex;
	int writeIndex;
	jakelib::lang::Object** queue;

	JAKELIB_DECLARE_CLASS(Queue);
      };

  }
}
#endif

