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();
                }
            }
        }
Exemple #2
0
        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();
                }
            }
        }