Files
caliverse_server/ServerCore/Sync/SyncState.cs
2025-05-01 07:20:41 +09:00

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;
}
}