public StateActionWithContextScheduledAsyncTask(AbstractScheduledEventExecutor executor, Action<object, object> action, object context, object state,
     PreciseTimeSpan deadline, CancellationToken cancellationToken)
     : base(executor, deadline, new TaskCompletionSource(state), cancellationToken)
 {
     this.action = action;
     this.context = context;
 }
 public void Register(PreciseTimeSpan startTimestamp)
 {
     PreciseTimeSpan elapsed = PreciseTimeSpan.FromStart - startTimestamp;
     long elapsedMs = (long)elapsed.ToTimeSpan().TotalMilliseconds;
     this.countCounter.IncrementBy(elapsedMs);
     this.baseCounter.Increment();
 }
 public CompletionPendingMessageState(int packetId, string lockToken,
      IQos2MessageDeliveryState deliveryState, PreciseTimeSpan startTimestamp)
 {
     this.PacketId = packetId;
     this.LockToken = lockToken;
     this.DeliveryState = deliveryState;
     this.StartTimestamp = startTimestamp;
     this.SentTime = DateTime.UtcNow;
 }
 public CompletionPendingMessageState(int packetId, IQos2MessageDeliveryState deliveryState,
     PreciseTimeSpan startTimestamp, MessageFeedbackChannel feedbackChannel)
 {
     this.PacketId = packetId;
     this.DeliveryState = deliveryState;
     this.StartTimestamp = startTimestamp;
     this.FeedbackChannel = feedbackChannel;
     this.SentTime = DateTime.UtcNow;
 }
        public void TestScheduling()
        {
            var  ch     = new EmbeddedChannel(new ChannelHandlerAdapter());
            var  latch  = new CountdownEvent(2);
            Task future = ch.EventLoop.ScheduleAsync(() => latch.Signal(), TimeSpan.FromSeconds(1));

            future.ContinueWith(t => latch.Signal());
            PreciseTimeSpan next = ch.RunScheduledPendingTasks();

            Assert.True(next > PreciseTimeSpan.Zero);
            // Sleep for the nanoseconds but also give extra 50ms as the clock my not be very precise and so fail the test
            // otherwise.
            Thread.Sleep(next.ToTimeSpan() + TimeSpan.FromMilliseconds(50));
            Assert.Equal(PreciseTimeSpan.MinusOne, ch.RunScheduledPendingTasks());
            latch.Wait();
        }
        async Task PublishToServerAsync(IChannelHandlerContext context, PublishPacket packet)
        {
            if (!this.ConnectedToHub)
            {
                return;
            }

            PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart;

            this.ResumeReadingIfNecessary(context);

            using (Stream bodyStream = packet.Payload.IsReadable() ? new ReadOnlyByteBufferStream(packet.Payload, true) : null)
            {
                var message = new Message(bodyStream);
                this.ApplyRoutingConfiguration(message, packet);

                Util.CompleteMessageFromPacket(message, packet, this.settings);

                await this.iotHubClient.SendAsync(message);

                PerformanceCounters.MessagesSentPerSecond.Increment();
            }

            if (!this.IsInState(StateFlags.Closed))
            {
                switch (packet.QualityOfService)
                {
                case QualityOfService.AtMostOnce:
                    // no response necessary
                    PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);
                    break;

                case QualityOfService.AtLeastOnce:
                    Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet))
                    .OnFault(ShutdownOnWriteFaultAction, context);
                    PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);     // todo: assumes PUBACK is written out sync
                    break;

                case QualityOfService.ExactlyOnce:
                    ShutdownOnError(context, "QoS 2 is not supported.");
                    break;

                default:
                    throw new InvalidOperationException("Unexpected QoS level: " + packet.QualityOfService);
                }
            }
        }
예제 #7
0
        async void SendD2CMessage(DeviceDataPacket dataPacket)
        {
            Contract.Requires(this.identity != null);

            if (identity?.Id != dataPacket.DeviceId)
            {
                if (this.stateFlags == StateFlags.ProcessingConnect || this.stateFlags == StateFlags.Connected)
                {
                    this.stateFlags = StateFlags.InvalidConfiguration;
                    this.Shutdown(this.capturedContext, new SocketIoTGatewayException(ErrorCode.UnResolvedSendingClient, "Invalid device identity"));
                    return;
                }
            }


            if (this.ConnectedToService)
            {
                PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart;

                IMessage message = null;
                try
                {
                    ITcpIoTHubMessagingServiceClient sendingClient = null;
                    if (this.messagingBridge.TryResolveClient("Events", out sendingClient))
                    {
                        message = sendingClient.CreateMessage(dataPacket.EventTopicAddress, dataPacket.Payload);
                        message.Properties[this.settings.ServicePropertyPrefix + "MessageType"] = dataPacket.PacketType.ToString();
                        await sendingClient.SendAsync(message);

                        message = null;
                    }
                    else
                    {
                        throw new SocketIoTGatewayException(ErrorCode.UnResolvedSendingClient, $"Could not resolve a sending client based on topic name `Events`.");
                    }
                }
                finally
                {
                    message?.Dispose();
                }
            }
            else
            {
                dataPacket.Release();
            }
        }
예제 #8
0
 void FetchFromScheduledTaskQueue()
 {
     if (this.HasScheduledTasks())
     {
         PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart;
         while (true)
         {
             ScheduledTaskQueueNode scheduledTask = this.PollScheduledTask(nanoTime);
             if (scheduledTask == null)
             {
                 break;
             }
             this.taskQueue.Enqueue(scheduledTask);
             this.semaphore.Release();
         }
     }
 }
        bool FetchFromScheduledTaskQueue()
        {
            PreciseTimeSpan    nanoTime      = PreciseTimeSpan.FromStart;
            IScheduledRunnable scheduledTask = this.PollScheduledTask(nanoTime);

            while (scheduledTask != null)
            {
                if (!this.taskQueue.TryEnqueue(scheduledTask))
                {
                    // No space left in the task queue add it back to the scheduledTaskQueue so we pick it up again.
                    this.ScheduledTaskQueue.Enqueue(scheduledTask);
                    return(false);
                }
                scheduledTask = this.PollScheduledTask(nanoTime);
            }
            return(true);
        }
예제 #10
0
        void FetchFromScheduledTaskQueue()
        {
            if (this.HasScheduledTasks())
            {
                PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart;
                while (true)
                {
                    IScheduledRunnable scheduledTask = this.PollScheduledTask(nanoTime);
                    if (scheduledTask == null)
                    {
                        break;
                    }

                    this.taskQueue.Enqueue(scheduledTask);
                }
            }
        }
예제 #11
0
파일: AssertEx.cs 프로젝트: dora-BYR/Fenix
        public static async Task EventuallyAsync(Func <Task <bool> > testFunc, TimeSpan interval, TimeSpan timeout)
        {
            PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout);

            while (true)
            {
                if (await testFunc())
                {
                    return;
                }
                if (PreciseTimeSpan.FromStart - deadline > PreciseTimeSpan.Zero)
                {
                    Assert.True(false, "Did not reach expected state in time.");
                }
                await Task.Delay(interval);
            }
        }
예제 #12
0
        ScheduledTaskQueueNode PollScheduledTask(PreciseTimeSpan nanoTime)
        {
            Debug.Assert(this.InEventLoop);

            ScheduledTaskQueueNode scheduledTask = this.scheduledTaskQueue.Peek();

            if (scheduledTask == null)
            {
                return(null);
            }

            if (scheduledTask.Deadline <= nanoTime)
            {
                this.scheduledTaskQueue.Dequeue();
                return(scheduledTask);
            }
            return(null);
        }
예제 #13
0
        protected IScheduledRunnable PollScheduledTask(PreciseTimeSpan nanoTime)
        {
            Contract.Assert(this.InEventLoop);

            IScheduledRunnable scheduledTask = this.ScheduledTaskQueue.Peek();

            if (scheduledTask == null)
            {
                return(null);
            }

            if (scheduledTask.Deadline <= nanoTime)
            {
                this.ScheduledTaskQueue.Dequeue();
                return(scheduledTask);
            }
            return(null);
        }
예제 #14
0
 protected SingleThreadEventExecutor(IEventExecutorGroup parent, string threadName, TimeSpan breakoutInterval, IQueue <IRunnable> taskQueue)
     : base(parent)
 {
     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();
 }
예제 #15
0
        private bool RunAllTasks(PreciseTimeSpan timeout)
        {
            _ = FetchFromScheduledTaskQueue();
            IRunnable task = PollTask();

            if (task is null)
            {
                AfterRunningAllTasks();
                return(false);
            }

            PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout);
            long            runTasks = 0;
            PreciseTimeSpan executionTime;

            while (true)
            {
                SafeExecute(task);

                runTasks++;

                // Check timeout every 64 tasks because nanoTime() is relatively expensive.
                // XXX: Hard-coded value - will make it configurable if it is really a problem.
                if (0ul >= (ulong)(runTasks & 0x3F))
                {
                    executionTime = PreciseTimeSpan.FromStart;
                    if (executionTime >= deadline)
                    {
                        break;
                    }
                }

                task = PollTask();
                if (task is null)
                {
                    executionTime = PreciseTimeSpan.FromStart;
                    break;
                }
            }

            AfterRunningAllTasks();
            _lastExecutionTime = executionTime;
            return(true);
        }
 public SingleThreadEventExecutor(string threadName, TimeSpan breakoutInterval)
 {
     this.terminationCompletionSource = new TaskCompletionSource();
     this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
     this.scheduler = new ExecutorTaskScheduler(this);
     this.thread = new Thread(this.Loop)
     {
         IsBackground = true
     };
     if (string.IsNullOrEmpty(threadName))
     {
         this.thread.Name = DefaultWorkerThreadName;
     }
     else
     {
         this.thread.Name = threadName;
     }
     this.thread.Start();
 }
예제 #17
0
 public SingleThreadEventExecutor(string threadName, TimeSpan breakoutInterval)
 {
     this.terminationCompletionSource = new TaskCompletionSource();
     this.preciseBreakoutInterval     = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
     this.scheduler = new ExecutorTaskScheduler(this);
     this.thread    = new Thread(this.Loop)
     {
         IsBackground = true
     };
     if (string.IsNullOrEmpty(threadName))
     {
         this.thread.Name = DefaultWorkerThreadName;
     }
     else
     {
         this.thread.Name = threadName;
     }
     this.thread.Start();
 }
예제 #18
0
        protected SingleThreadEventExecutor(IEventExecutorGroup parent, string threadName, TimeSpan breakoutInterval, IQueue <IRunnable> taskQueue)
            : base(parent)
        {
            _loopAction     = Loop;
            _loopCoreAciton = LoopCore;

            _terminationCompletionSource = NewPromise();
            _taskQueue = taskQueue;
            _preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
            _scheduler = new ExecutorTaskScheduler(this);
            _thread    = new Thread(_loopAction);
            if (string.IsNullOrEmpty(threadName))
            {
                _thread.Name = DefaultWorkerThreadName;
            }
            else
            {
                _thread.Name = threadName;
            }
            _thread.Start();
        }
예제 #19
0
        protected bool RunAllTasks()
        {
            this.FetchFromScheduledTaskQueue();
            IRunnable task = this.PollTask();

            if (task == null)
            {
                return(false);
            }

            while (true)
            {
                SafeExecute(task);
                task = this.PollTask();
                if (task == null)
                {
                    this.lastExecutionTime = PreciseTimeSpan.FromStart;
                    return(true);
                }
            }
        }
예제 #20
0
        private bool FetchFromScheduledTaskQueue()
        {
            if (ScheduledTaskQueue.IsEmpty)
            {
                return(true);
            }

            PreciseTimeSpan    nanoTime      = PreciseTimeSpan.FromStart;
            IScheduledRunnable scheduledTask = PollScheduledTask(nanoTime);

            while (scheduledTask is object)
            {
                if (!_taskQueue.TryEnqueue(scheduledTask))
                {
                    // No space left in the task queue add it back to the scheduledTaskQueue so we pick it up again.
                    _ = ScheduledTaskQueue.TryEnqueue(scheduledTask);
                    return(false);
                }
                scheduledTask = PollScheduledTask(nanoTime);
            }
            return(true);
        }
예제 #21
0
        protected bool RunAllTasks()
        {
            this.FetchFromScheduledTaskQueue();
            IRunnable task = this.PollTask();

            if (task == null)
            {
                return(false);
            }

            while (true)
            {
                Volatile.Write(ref this.progress, this.progress + 1); // volatile write is enough as this is the only thread ever writing
                SafeExecute(task);
                task = this.PollTask();
                if (task == null)
                {
                    this.lastExecutionTime = PreciseTimeSpan.FromStart;
                    return(true);
                }
            }
        }
예제 #22
0
        /// <summary>
        /// Tries to query measured process times.
        /// </summary>
        /// <param name="ptr">Process handle.</param>
        /// <param name="processTimes">Measured process times.</param>
        /// <returns>True if received the process times.</returns>
        internal static bool TryGetProcessTimes(IntPtr ptr, out ProcessTimes processTimes)
        {
            processTimes = new ProcessTimes();

            System.Runtime.InteropServices.ComTypes.FILETIME lpCreationTime, lpExitTime, lpKernel, lpUser;

            bool result = GetProcessTimes(ptr, out lpCreationTime, out lpExitTime, out lpKernel, out lpUser);

            if (!result)
            {
                Console.Error.WriteLine("Unable to query process time.");
                return(false);
            }

            DateTime creation = DateTime.FromFileTime(ComFileTimeToTicks(lpCreationTime));
            DateTime exit     = DateTime.FromFileTime(ComFileTimeToTicks(lpExitTime));

            processTimes = new ProcessTimes(PreciseTimeSpan.FromTicks((exit - creation).Ticks),
                                            PreciseTimeSpan.FromTicks(ComFileTimeToTicks(lpUser)),
                                            PreciseTimeSpan.FromTicks(ComFileTimeToTicks(lpKernel)));

            return(true);
        }
예제 #23
0
        public LoopExecutor(IEventLoopGroup parent, string threadName, TimeSpan breakoutInterval) : base(parent)
        {
            this.preciseBreakoutInterval = PreciseTimeSpan.FromTimeSpan(breakoutInterval);
            this.preciseTimerInterval    = PreciseTimeSpan.FromTimeSpan(TimeSpan.FromTicks(breakoutInterval.Ticks * 2));

            this.terminationCompletionSource = new TaskCompletionSource();
            this.taskQueue = PlatformDependent.NewMpscQueue <IRunnable>();
            this.scheduler = new ExecutorTaskScheduler(this);

            this.loop        = new Loop();
            this.asyncHandle = new Async(this.loop, RunAllTasksCallback, this);
            this.timerHandle = new Timer(this.loop, RunAllTasksCallback, this);
            string name = string.Format(DefaultWorkerThreadName, this.loop.Handle);

            if (!string.IsNullOrEmpty(threadName))
            {
                name = $"{name} ({threadName})";
            }
            this.thread = new XThread(RunLoop)
            {
                Name = name
            };
        }
예제 #24
0
        public override bool WaitTermination(TimeSpan timeout)
        {
            PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout);

            for (int i = 0; i < _eventLoops.Length; i++)
            {
                var executor = _eventLoops[i];
                for (; ;)
                {
                    PreciseTimeSpan timeLeft = deadline - PreciseTimeSpan.FromStart;
                    if (timeLeft <= PreciseTimeSpan.Zero)
                    {
                        goto LoopEnd;
                    }

                    if (executor.WaitTermination(timeLeft.ToTimeSpan()))
                    {
                        break;
                    }
                }
            }
LoopEnd:
            return(IsTerminated);
        }
예제 #25
0
 protected ScheduledAsyncTask(AbstractScheduledEventExecutor executor, PreciseTimeSpan deadline, TaskCompletionSource promise, CancellationToken cancellationToken)
     : base(executor, deadline, promise)
 {
     this.cancellationToken = cancellationToken;
     this.cancellationTokenRegistration = cancellationToken.Register(s => ((ScheduledAsyncTask)s).Cancel(), this);
 }
예제 #26
0
        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)
            //{
            //    wakeup(inEventLoop);
            //}

            return(this.TerminationCompletion);
        }
        bool RunAllTasks(PreciseTimeSpan timeout)
        {
            this.FetchFromScheduledTaskQueue();
            IRunnable task = this.PollTask();
            if (task == null)
            {
                return false;
            }

            PreciseTimeSpan deadline = PreciseTimeSpan.Deadline(timeout);
            long runTasks = 0;
            PreciseTimeSpan executionTime;
            while (true)
            {
                try
                {
                    task.Run();
                }
                catch (Exception ex)
                {
                    Logger.Warn("A task raised an exception.", ex);
                }

                runTasks++;

                // Check timeout every 64 tasks because nanoTime() is relatively expensive.
                // XXX: Hard-coded value - will make it configurable if it is really a problem.
                if ((runTasks & 0x3F) == 0)
                {
                    executionTime = PreciseTimeSpan.FromStart;
                    if (executionTime >= deadline)
                    {
                        break;
                    }
                }

                task = this.PollTask();
                if (task == null)
                {
                    executionTime = PreciseTimeSpan.FromStart;
                    break;
                }
            }

            this.lastExecutionTime = executionTime;
            return true;
        }
        protected bool RunAllTasks()
        {
            this.FetchFromScheduledTaskQueue();
            IRunnable task = this.PollTask();
            if (task == null)
            {
                return false;
            }

            while (true)
            {
                try
                {
                    task.Run();
                }
                catch (Exception ex)
                {
                    Logger.Warn("A task raised an exception.", ex);
                }

                task = this.PollTask();
                if (task == null)
                {
                    this.lastExecutionTime = PreciseTimeSpan.FromStart;
                    return true;
                }
            }
        }
 public StateActionScheduledTask(AbstractScheduledEventExecutor executor, Action<object> action, object state, PreciseTimeSpan deadline)
     : base(executor, deadline, new TaskCompletionSource(state))
 {
     this.action = action;
 }
예제 #30
0
        public override Task ScheduleAsync(Action <object, object> action, object context, object state, TimeSpan delay, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(TaskEx.Cancelled);
            }

            if (!cancellationToken.CanBeCanceled)
            {
                return(this.Schedule(action, context, state, delay).Completion);
            }

            return(this.Schedule(new StateActionWithContextScheduledAsyncTask(this, action, context, state, PreciseTimeSpan.Deadline(delay), cancellationToken)).Completion);
        }
예제 #31
0
        public override IScheduledTask Schedule(Action action, TimeSpan delay)
        {
            Contract.Requires(action != null);

            return(this.Schedule(new ActionScheduledTask(this, action, PreciseTimeSpan.Deadline(delay))));
        }
예제 #32
0
 protected ScheduledTask(AbstractScheduledEventExecutor executor, PreciseTimeSpan deadline, TaskCompletionSource promise)
 {
     this.Executor = executor;
     this.Promise  = promise;
     this.Deadline = deadline;
 }
 public StateActionScheduledTask(Action <object> action, object state, PreciseTimeSpan deadline,
                                 CancellationToken cancellationToken)
     : base(deadline, new TaskCompletionSource(state), cancellationToken)
 {
     this.action = action;
 }
예제 #34
0
 public RunnableScheduledTask(AbstractScheduledEventExecutor executor, IRunnable action, PreciseTimeSpan deadline)
     : base(executor, deadline, new TaskCompletionSource())
 {
     this.action = action;
 }
 protected ScheduledTaskBase(PreciseTimeSpan deadline, TaskCompletionSource promise, CancellationToken cancellationToken)
 {
     this.promise           = promise;
     this.Deadline          = deadline;
     this.CancellationToken = cancellationToken;
 }
        public override Task ScheduleAsync(Action <object, object> action, object context, object state, TimeSpan delay, CancellationToken cancellationToken)
        {
            var scheduledTask = new StateActionWithContextScheduledTask(action, context, state, PreciseTimeSpan.Deadline(delay), cancellationToken);

            if (this.InEventLoop)
            {
                this.ScheduledTaskQueue.Enqueue(scheduledTask);
            }
            else
            {
                this.Execute(AddScheduledTaskAction, this, scheduledTask);
            }
            return(scheduledTask.Completion);
        }
예제 #37
0
 public StateActionScheduledTask(AbstractScheduledEventExecutor executor, Action <object> action, object state, PreciseTimeSpan deadline)
     : base(executor, deadline, new TaskCompletionSource(state))
 {
     this.action = action;
 }
 Task PublishReleaseToClientAsync(IChannelHandlerContext context, int packetId, string lockToken,
     IQos2MessageDeliveryState messageState, PreciseTimeSpan startTimestamp)
 {
     var pubRelPacket = new PubRelPacket
     {
         PacketId = packetId
     };
     return this.pubRelPubCompProcessor.SendRequestAsync(context, pubRelPacket,
         new CompletionPendingMessageState(packetId, lockToken, messageState, startTimestamp));
 }
예제 #39
0
 public ActionScheduledAsyncTask(AbstractScheduledEventExecutor executor, Action action, PreciseTimeSpan deadline, CancellationToken cancellationToken)
     : base(executor, deadline, new TaskCompletionSource(), cancellationToken)
 {
     this.action = action;
 }
        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)
            //{
            //    wakeup(inEventLoop);
            //}

            return this.TerminationCompletion;
        }
예제 #41
0
        public override IScheduledTask Schedule(Action <object, object> action, object context, object state, TimeSpan delay)
        {
            Contract.Requires(action != null);

            return(this.Schedule(new StateActionWithContextScheduledTask(this, action, context, state, PreciseTimeSpan.Deadline(delay))));
        }
        protected bool ConfirmShutdown()
        {
            if (!this.IsShuttingDown)
            {
                return false;
            }

            if (!this.InEventLoop)
            {
                throw new InvalidOperationException("must be invoked from an event loop");
            }

            this.CancelScheduledTasks();

            if (this.gracefulShutdownStartTime == PreciseTimeSpan.Zero)
            {
                this.gracefulShutdownStartTime = PreciseTimeSpan.FromStart;
            }

            if (this.RunAllTasks()) // || runShutdownHooks())
            {
                if (this.IsShutdown)
                {
                    // Executor shut down - no new tasks anymore.
                    return true;
                }

                // There were tasks in the queue. Wait a little bit more until no tasks are queued for the quiet period.
                // todo: ???
                //wakeup(true);
                return false;
            }

            PreciseTimeSpan nanoTime = PreciseTimeSpan.FromStart;

            if (this.IsShutdown || nanoTime - this.gracefulShutdownStartTime > this.gracefulShutdownTimeout)
            {
                return true;
            }

            if (nanoTime - this.lastExecutionTime <= this.gracefulShutdownQuietPeriod)
            {
                // Check if any tasks were added to the queue every 100ms.
                // TODO: Change the behavior of takeTask() so that it returns on timeout.
                // todo: ???
                //wakeup(true);
                Thread.Sleep(100);

                return false;
            }

            // No tasks were added for last quiet period - hopefully safe to shut down.
            // (Hopefully because we really cannot make a guarantee that there will be no execute() calls by a user.)
            return true;
        }
 public ActionScheduledTask(Action action, PreciseTimeSpan deadline, CancellationToken cancellationToken)
     : base(deadline, new TaskCompletionSource(), cancellationToken)
 {
     this.action = action;
 }
 public ActionScheduledAsyncTask(AbstractScheduledEventExecutor executor, Action action, PreciseTimeSpan deadline, CancellationToken cancellationToken)
     : base(executor, deadline, new TaskCompletionSource(), cancellationToken)
 {
     this.action = action;
 }