using System.Threading;
namespace ZeroLevel.Services
{
///
/// Класс реализующий потокобезопасный флаг
///
public sealed class AtomicBoolean
{
///
/// Локер для переключения флага указывающего идет или нет процесс обработки
///
private SpinLock _compareLocker = new SpinLock();
///
/// Флаг, указывает идет ли в текущий момент процесс обработки очереди
///
private bool _lock;
///
/// Потокобезопасное переназначение булевой переменной
/// функция сранивает переменную со значением comparand
/// и при совпадении заменяет значение переменной на value
/// и возвращает true.
/// При несовпадении значения переменной и comparand
/// значение переменной останется прежним и функция
/// вернет false.
///
/// Переменная
/// Значение для проставления в случае совпадения
/// Сравниваемое значение
/// true - в случае совпадения значений target и comparand
private bool CompareExchange(ref bool target, bool value, bool comparand)
{
bool lockTaked = false;
try
{
_compareLocker.Enter(ref lockTaked);
if (target == comparand)
{
target = value;
return true;
}
return false;
}
finally
{
if (lockTaked) _compareLocker.Exit();
}
}
///
/// Установка значения в true
///
/// true - если значение изменилось, false - если значение занято другим потоком и не изменилось
public bool Set()
{
return CompareExchange(ref _lock, true, false);
}
///
/// Сброс значения
///
public void Reset()
{
CompareExchange(ref _lock, false, true);
}
public bool State
{
get
{
return _lock;
}
}
}
}