/// <summary> /// Verifies that state transition is possible /// </summary> /// <param name="oldState">Current state</param> /// <param name="newState">New state</param> /// <returns>True when state transition can be performed</returns> private bool IsValidStateTransition(ThreadSetManagerState oldState, ThreadSetManagerState newState) { switch (oldState) { case ThreadSetManagerState.Created: return(newState == ThreadSetManagerState.StartRequested || newState == ThreadSetManagerState.StopRequested); case ThreadSetManagerState.StartRequested: return(newState == ThreadSetManagerState.Running || newState == ThreadSetManagerState.Stopped); case ThreadSetManagerState.Running: return(newState == ThreadSetManagerState.StopRequested || newState == ThreadSetManagerState.AllThreadsExited); case ThreadSetManagerState.StopRequested: return(newState == ThreadSetManagerState.Stopped); case ThreadSetManagerState.AllThreadsExited: return(newState == ThreadSetManagerState.StopRequested); case ThreadSetManagerState.Stopped: return(false); default: return(false); } }
/// <summary> /// Safely changes the current state /// </summary> /// <param name="newState">New state</param> /// <param name="prevState">Previously observed state</param> /// <returns>Was state changed (false means that the state transition is not valid)</returns> private bool ChangeStateSafe(ThreadSetManagerState newState, out ThreadSetManagerState prevState) { prevState = (ThreadSetManagerState)Volatile.Read(ref _state); if (!IsValidStateTransition(prevState, newState)) { return(false); } SpinWait sw = new SpinWait(); while (Interlocked.CompareExchange(ref _state, (int)newState, (int)prevState) != (int)prevState) { sw.SpinOnce(); prevState = (ThreadSetManagerState)Volatile.Read(ref _state); if (!IsValidStateTransition(prevState, newState)) { return(false); } } return(true); }