namespace ServerCore; //============================================================================================= // 병렬 프로그래밍 환경에서 상태값을 동기화할 수 있게 지원하는 제네릭 클래스 이다. // // author : kangms // //============================================================================================= public class SyncState 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; } }