// BlockingIntQueue.java -- a bounded buffer with blocking threads
// Copyright (c)2007 Christopher League <league@contrapunctus.net>
// This is free software, but it comes with ABSOLUTELY NO WARRANTY.
// GNU Lesser General Public License 2.1 or Common Public License 1.0
package net.contrapunctus.lzma;
import java.util.concurrent.Semaphore;
import java.io.PrintStream;
// There is no mutex protecting producer_index and consumer_index,
// because I expect precisely one producer and one consumer!
final class BlockingIntQueue
{
private int[] array;
private int producer_index;
private int consumer_index;
private Semaphore space;
private Semaphore data;
private static final PrintStream dbg = System.err;
private static final boolean DEBUG =
System.getProperty("DEBUG_BlockingIntQueue") != null;
BlockingIntQueue( int size )
{
array = new int [size];
producer_index = 0;
consumer_index = 0;
space = new Semaphore( size );
data = new Semaphore( 0 );
}
BlockingIntQueue( )
{
this( 4096 );
}
void put( int x ) throws InterruptedException
{
if(DEBUG) willBlock(space, '<');
space.acquire( );
array[producer_index] = x;
if(DEBUG) dbg.printf("%s < %02x @%d%n", this, x, producer_index);
producer_index = (producer_index+1) % array.length;
data.release( );
}
int take( ) throws InterruptedException
{
if(DEBUG) willBlock(data, '>');
data.acquire( );
int x = array[consumer_index];
if(DEBUG) dbg.printf("%s > %02x @%d%n", this, x, consumer_index);
consumer_index = (consumer_index+1) % array.length;
space.release( );
return x;
}
private void willBlock( Semaphore s, char dir )
{
if( s.availablePermits() <= 0 )
{
dbg.printf("%s %c blocks%n", this, dir);
}
}
public String toString( )
{
return String.format("BQ@%x", hashCode());
}
}