179 lines
3.8 KiB
C#
179 lines
3.8 KiB
C#
namespace ServerCore;
|
|
|
|
//=============================================================================================
|
|
// 병렬 프로그래밍 환경에서 상태값을 동기화할 수 있게 지원하는 제네릭 클래스 이다.
|
|
//
|
|
// author : kangms
|
|
//
|
|
//=============================================================================================
|
|
public class SyncState<T> where T : notnull
|
|
{
|
|
private T m_state;
|
|
private readonly object m_mutex = new object(); // mutex
|
|
|
|
public SyncState(T state)
|
|
{
|
|
m_state = state;
|
|
}
|
|
|
|
public bool isState(T state)
|
|
{
|
|
lock (m_mutex)
|
|
{
|
|
return (m_state.Equals(state));
|
|
}
|
|
}
|
|
|
|
public T setState(T state)
|
|
{
|
|
lock (m_mutex)
|
|
{
|
|
T old_state = m_state;
|
|
m_state = state;
|
|
return old_state;
|
|
}
|
|
}
|
|
|
|
public T getState()
|
|
{
|
|
return m_state;
|
|
}
|
|
|
|
// 같지 않으면 변경
|
|
// exchange..(disconnected, out old_state)
|
|
public bool exchangeNotEqual(T to_state, out T old_state)
|
|
{
|
|
lock (m_mutex)
|
|
{
|
|
if (false == m_state.Equals(to_state))
|
|
{
|
|
old_state = m_state;
|
|
m_state = to_state;
|
|
return true;
|
|
}
|
|
|
|
old_state = m_state;
|
|
return false;
|
|
}
|
|
}
|
|
// 같지 않으면 변경, 예외인 경우는 변경안함
|
|
// exchange...(disconnected, connecting, out old_state)
|
|
public bool exchangeNotEqualExcept(T to_state, T except_state, out T old_state)
|
|
{
|
|
lock (m_mutex)
|
|
{
|
|
// except state
|
|
if (true == m_state.Equals(except_state))
|
|
{
|
|
old_state = m_state;
|
|
return false;
|
|
}
|
|
|
|
if (false == m_state.Equals(to_state))
|
|
{
|
|
old_state = m_state;
|
|
m_state = to_state;
|
|
return true;
|
|
}
|
|
|
|
old_state = m_state;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string? toString()
|
|
{
|
|
return Enum.GetName(typeof(T), m_state);
|
|
}
|
|
}
|
|
|
|
public class AtomicString
|
|
{
|
|
private string m_value;
|
|
|
|
public AtomicString(string value = "")
|
|
{
|
|
m_value = value;
|
|
}
|
|
|
|
public string Value
|
|
{
|
|
get { return m_value; }
|
|
}
|
|
|
|
public void set(string newValue)
|
|
{
|
|
Interlocked.Exchange(ref m_value, newValue);
|
|
}
|
|
|
|
public bool compareAndSet(string expectedValue, string newValue)
|
|
{
|
|
return Interlocked.CompareExchange(ref m_value, newValue, expectedValue) == expectedValue;
|
|
}
|
|
}
|
|
|
|
public class AtomicInt32
|
|
{
|
|
private Int32 m_value;
|
|
|
|
public AtomicInt32(Int32 value = 0)
|
|
{
|
|
m_value = value;
|
|
}
|
|
|
|
public int Value
|
|
{
|
|
get { return m_value; }
|
|
}
|
|
|
|
public void set(int newValue)
|
|
{
|
|
Interlocked.Exchange(ref m_value, newValue);
|
|
}
|
|
|
|
public int increment()
|
|
{
|
|
return Interlocked.Increment(ref m_value);
|
|
}
|
|
|
|
public int decrement()
|
|
{
|
|
return Interlocked.Decrement(ref m_value);
|
|
}
|
|
|
|
public int add(int value)
|
|
{
|
|
return Interlocked.Add(ref m_value, value);
|
|
}
|
|
|
|
public bool compareAndSet(int expectedValue, int newValue)
|
|
{
|
|
return Interlocked.CompareExchange(ref m_value, newValue, expectedValue) == expectedValue;
|
|
}
|
|
}
|
|
|
|
public class AtomicBool
|
|
{
|
|
private Int32 m_value = 0;
|
|
|
|
public AtomicBool(bool value)
|
|
{
|
|
m_value = value ? 1 : 0;
|
|
}
|
|
|
|
public bool Value
|
|
{
|
|
get { return m_value == 1; }
|
|
}
|
|
|
|
public bool set(bool value)
|
|
{
|
|
var comparand = value ? 0 : 1;
|
|
var in_value = value ? 1 : 0;
|
|
|
|
var result = Interlocked.CompareExchange(ref m_value, in_value, comparand);
|
|
|
|
return comparand == result;
|
|
}
|
|
}
|