/*********************************************************************/
/* */
/* AgentService Framework */
/* www.agentservice.it */
/* */
/* Copyright (C) 2007 l.i.d.o. - DIST, University of Genoa, Italy */
/* GNU Lesser General Public License */
/* */
/* 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, */
/* version 2.1 of the License. */
/* */
/* 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. */
/* */
/*********************************************************************/
using System;
using System.Threading;
namespace AgentService.Agent.Behaviour
{
///
/// Class WaitingBehaviour. Defines a behaviour that is waiting for
/// an event to continue. It merely represents an integer semaphore
/// that when reaches the "go" resumes the thread associated with the
/// behaviour
///
public class WaitingBehaviour
{
///
/// waiting behaviour hash code
///
private int hashCode;
///
/// Gets the waiting behaviour's hash code
///
public int BehaviourHashCode
{
get
{
return this.hashCode;
}
}
///
/// integer semaphore, do you rememeber Djkstra?
///
private int semaphore;
///
/// Gets the waiting handle for the behaviour
///
public bool IsBusy
{
get
{
return (this.semaphore > 0);
}
}
///
/// Constructs a WaitingBehaviour object associated to the given thread with the
/// given initial value of the semaphore
///
/// hashcode of the behaviour that is waiting
/// integer value representing the initial value of the semaphore
public WaitingBehaviour(int hashCode, int semaphore)
{
// TODO: check consistent values of parameters?
// thread null?
// sempahore > 0?
this.hashCode = hashCode;
this.semaphore = semaphore;
}
///
/// Signal primitive, decrements the value of the semaphore if not zero
///
public void Signal()
{
// the integer semaphore is idempotent, if
// the value has reached zero nothing happens
// anymore
try
{
Monitor.Enter(this);
if (this.semaphore > 0)
{
this.semaphore--;
// ok if zero... go!
if (this.semaphore == 0)
{
// this.waitingThread.Resume();
Monitor.PulseAll(this);
}
}
}
finally
{
Monitor.Exit(this);
}
}
///
/// Wait primitive, increments the value of the semaphore if not zero
///
public void Wait()
{
try
{
Monitor.Enter(this);
if (this.semaphore > 0)
{
this.semaphore++;
}
}
finally
{
Monitor.Exit(this);
}
}
///
/// Executes a multiple wait, if the semaphore is equal to 0
/// it does nothing
///
/// numer of wait ot execute
public void MultipleWait(int timesToWait)
{
try
{
Monitor.Enter(this);
if ((this.semaphore > 0) && (timesToWait > 0))
{
this.semaphore += timesToWait;
}
}
finally
{
Monitor.Exit(this);
}
}
}
}