package org.sfc.parallel;
/**
* A synchronization point for any count of threads.
*
* @author Thomas Weise
*/
public final class SyncPoint implements IWaitable
{
/**
* The internal sync object.
*/
private final Object m_sync;
/**
* <code>true</code> if the waiters have been released.
*/
private volatile boolean m_wait ;
/**
* The count of threads currently waiting.
*/
private volatile int m_waiters ;
/**
* Create a new sync-point.
*/
public SyncPoint ()
{
this(true);
}
/**
* Create a new sync-point.
* @param p_wait The initial wait value.
*/
SyncPoint (final boolean p_wait)
{
super();
this.m_sync = new Object();
this.m_wait = p_wait;
}
/**
* Internally set the wait-value.
* @param p_wait The new wait value.
*/
final void set_wait (final boolean p_wait)
{
synchronized(this.m_sync)
{
this.m_wait = p_wait;
}
}
/**
* Wait for this object.
*/
public final void wait_for ()
{
boolean l_b;
Object l_o;
l_o = this.m_sync;
synchronized(l_o)
{
if(this.m_wait)
{
this.m_waiters++;
for(;;)
{
l_b = true;
try
{
l_o.wait();
}
catch(InterruptedException l_ies)
{
l_b = false;
}
if(l_b)
{
this.m_waiters--;
l_o.notify();
return;
}
}
}
}
}
/**
* Release all threads waiting for this synchronization point.
* @param p_reset If you want to re-use this synchronization point,
* meaning if you want to allow threads to wait again,
* set this parameter to <code>true</code>. If set to
* <code>false</code>, the sync-point cannot be reused.
*/
public final void release (final boolean p_reset)
{
Object l_o;
l_o = this.m_sync;
synchronized(l_o)
{
if(this.m_wait)
{
this.m_wait = p_reset;
}
while(this.m_waiters > 0)
{
l_o.notify();
try
{
l_o.wait();
}
catch(Throwable l_t)
{
}
l_o.notify();
}
}
}
}