protected void CleanupAndTerminate(bool success) { TrySetExecutionState(ShuttingDownState); // Check if confirmShutdown() was called at the end of the loop. if (success && (0ul >= (ulong)_gracefulShutdownStartTime)) { Logger.BuggyImplementation(this); } try { if (!IsTerminated) { // Run all remaining tasks and shutdown hooks. At this point the event loop // is in ST_SHUTTING_DOWN state still accepting tasks which is needed for // graceful shutdown with quietPeriod. while (true) { if (ConfirmShutdown()) { break; } } // Now we want to make sure no more tasks can be added from this point. This is // achieved by switching the state. Any new tasks beyond this point will be rejected. TrySetExecutionState(ShutdownState); // We have the final set of tasks in the queue now, no more can be added, run all remaining. // No need to loop here, this is the final pass. _ = ConfirmShutdown(); } } finally { try { Cleanup(); } finally { SetExecutionState(TerminatedState); if (!_threadLock.IsSet) { _ = _threadLock.Signal(); } int numUserTasks = DrainTasks(); if ((uint)numUserTasks > 0u && Logger.WarnEnabled) { Logger.AnEventExecutorTerminatedWithNonEmptyTaskQueue(numUserTasks); } _terminationCompletionSource.TryComplete(); } } }
protected void CleanupAndTerminate(bool success) { var thisState = Volatile.Read(ref v_executionState); int oldState; do { oldState = thisState; if ((uint)oldState >= ST_SHUTTING_DOWN) { break; } thisState = Interlocked.CompareExchange(ref v_executionState, ST_SHUTTING_DOWN, oldState); } while (thisState != oldState); // Check if confirmShutdown() was called at the end of the loop. if (success && (_gracefulShutdownStartTime == PreciseTimeSpan.Zero)) { Logger.BuggyImplementation(); //$"Buggy {typeof(IEventExecutor).Name} implementation; {typeof(SingleThreadEventExecutor).Name}.ConfirmShutdown() must be called " //+ "before run() implementation terminates."); } try { // Run all remaining tasks and shutdown hooks. At this point the event loop // is in ST_SHUTTING_DOWN state still accepting tasks which is needed for // graceful shutdown with quietPeriod. while (true) { if (ConfirmShutdown()) { break; } } // Now we want to make sure no more tasks can be added from this point. This is // achieved by switching the state. Any new tasks beyond this point will be rejected. thisState = Volatile.Read(ref v_executionState); do { oldState = thisState; if ((uint)oldState >= ST_SHUTDOWN) { break; } thisState = Interlocked.CompareExchange(ref v_executionState, ST_SHUTDOWN, oldState); } while (thisState != oldState); // We have the final set of tasks in the queue now, no more can be added, run all remaining. // No need to loop here, this is the final pass. _ = ConfirmShutdown(); } finally { try { Cleanup(); } finally { _ = Interlocked.Exchange(ref v_executionState, ST_TERMINATED); int numUserTasks = DrainTasks(); if ((uint)numUserTasks > 0u && Logger.WarnEnabled) { Logger.AnEventExecutorTerminatedWithNonEmptyTaskQueue(numUserTasks); } //firstRun = true; _terminationCompletionSource.Complete(); } } }