/// <summary>
 ///
 /// </summary>
 /// <param name="pool"></param>
 /// <param name="threadName"></param>
 /// <param name="breakoutInterval"></param>
 /// <param name="taskQueue"></param>
 protected SingleThreadEventExecutor(IThreadPoolExecutor pool, string threadName, TimeSpan breakoutInterval, IQueue <IRunnable> taskQueue)
     : base(pool)
 {
     this.terminationCompletionSource = new TaskCompletionSource();
     this.taskQueue = taskQueue;
     this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
     this.scheduler = new ExecutorTaskScheduler(this);
     this.thread    = new Thread(this.Loop);
     if (string.IsNullOrEmpty(threadName))
     {
         this.thread.Name = DefaultWorkerThreadName;
     }
     else
     {
         this.thread.Name = threadName;
     }
     this.thread.Start();
 }
        /// <inheritdoc cref="IEventExecutor"/>
        public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan timeout)
        {
            Contract.Requires(quietPeriod >= TimeSpan.Zero);
            Contract.Requires(timeout >= quietPeriod);

            if (this.IsShuttingDown)
            {
                return(this.TerminationCompletion);
            }

            bool inEventLoop = this.InEventLoop;
            bool wakeup;
            int  oldState;

            while (true)
            {
                if (this.IsShuttingDown)
                {
                    return(this.TerminationCompletion);
                }
                int newState;
                wakeup   = true;
                oldState = this.executionState;
                if (inEventLoop)
                {
                    newState = ST_SHUTTING_DOWN;
                }
                else
                {
                    switch (oldState)
                    {
                    case ST_NOT_STARTED:
                    case ST_STARTED:
                        newState = ST_SHUTTING_DOWN;
                        break;

                    default:
                        newState = oldState;
                        wakeup   = false;
                        break;
                    }
                }
                if (Interlocked.CompareExchange(ref this.executionState, newState, oldState) == oldState)
                {
                    break;
                }
            }
            this.gracefulShutdownQuietPeriod = PreciseTimeSpan.FromTimeSpan(quietPeriod);
            this.gracefulShutdownTimeout     = PreciseTimeSpan.FromTimeSpan(timeout);

            // todo: revisit
            //if (oldState == ST_NOT_STARTED)
            //{
            //    scheduleExecution();
            //}

            if (wakeup)
            {
                this.WakeUp(inEventLoop);
            }

            return(this.TerminationCompletion);
        }