1- // Copyright (c) Microsoft. All rights reserved.
1+ // Copyright (c) Microsoft. All rights reserved.
22// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33
44namespace DotNetty . Common . Concurrency
@@ -15,8 +15,6 @@ namespace DotNetty.Common.Concurrency
1515 /// </summary>
1616 public abstract class AbstractScheduledEventExecutor : AbstractEventExecutor
1717 {
18- static readonly Action < object , object > AddScheduledTaskAction = ( e , t ) => ( ( AbstractScheduledEventExecutor ) e ) . ScheduledTaskQueue . Enqueue ( ( IScheduledRunnable ) t ) ;
19-
2018 protected readonly PriorityQueue < IScheduledRunnable > ScheduledTaskQueue = new PriorityQueue < IScheduledRunnable > ( ) ;
2119
2220 // TODO: support for EventExecutorGroup
@@ -94,172 +92,89 @@ protected bool HasScheduledTasks()
9492 return scheduledTask != null && scheduledTask . Deadline <= PreciseTimeSpan . FromStart ;
9593 }
9694
97- public override Task ScheduleAsync ( Action action , TimeSpan delay , CancellationToken cancellationToken )
95+ public override IScheduledTask Schedule ( Action action , TimeSpan delay )
9896 {
99- var scheduledTask = new ActionScheduledTask ( action , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ;
100- if ( this . InEventLoop )
101- {
102- this . ScheduledTaskQueue . Enqueue ( scheduledTask ) ;
103- }
104- else
105- {
106- this . Execute ( AddScheduledTaskAction , this , scheduledTask ) ;
107- }
108- return scheduledTask . Completion ;
109- }
110-
111- public override Task ScheduleAsync ( Action < object > action , object state , TimeSpan delay , CancellationToken cancellationToken )
112- {
113- var scheduledTask = new StateActionScheduledTask ( action , state , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ;
114- if ( this . InEventLoop )
115- {
116- this . ScheduledTaskQueue . Enqueue ( scheduledTask ) ;
117- }
118- else
119- {
120- this . Execute ( AddScheduledTaskAction , this , scheduledTask ) ;
121- }
122- return scheduledTask . Completion ;
97+ return this . Schedule ( new ActionScheduledTask ( this , action , PreciseTimeSpan . Deadline ( delay ) ) ) ;
12398 }
12499
125- public override Task ScheduleAsync ( Action < object , object > action , object context , object state , TimeSpan delay , CancellationToken cancellationToken )
100+ public override IScheduledTask Schedule ( Action < object > action , object state , TimeSpan delay )
126101 {
127- var scheduledTask = new StateActionWithContextScheduledTask ( action , context , state , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ;
128- if ( this . InEventLoop )
129- {
130- this . ScheduledTaskQueue . Enqueue ( scheduledTask ) ;
131- }
132- else
133- {
134- this . Execute ( AddScheduledTaskAction , this , scheduledTask ) ;
135- }
136- return scheduledTask . Completion ;
102+ return this . Schedule ( new StateActionScheduledTask ( this , action , state , PreciseTimeSpan . Deadline ( delay ) ) ) ;
137103 }
138104
139- #region Scheduled task data structures
140-
141- protected interface IScheduledRunnable : IRunnable , IComparable < IScheduledRunnable >
105+ public override IScheduledTask Schedule ( Action < object , object > action , object context , object state , TimeSpan delay )
142106 {
143- PreciseTimeSpan Deadline { get ; }
144-
145- bool Cancel ( ) ;
107+ return this . Schedule ( new StateActionWithContextScheduledTask ( this , action , context , state , PreciseTimeSpan . Deadline ( delay ) ) ) ;
146108 }
147109
148- protected abstract class ScheduledTaskBase : MpscLinkedQueueNode < IRunnable > , IScheduledRunnable
110+ public override Task ScheduleAsync ( Action action , TimeSpan delay , CancellationToken cancellationToken )
149111 {
150- readonly TaskCompletionSource promise ;
151-
152- protected ScheduledTaskBase ( PreciseTimeSpan deadline , TaskCompletionSource promise , CancellationToken cancellationToken )
153- {
154- this . promise = promise ;
155- this . Deadline = deadline ;
156- this . CancellationToken = cancellationToken ;
157- }
158-
159- public PreciseTimeSpan Deadline { get ; private set ; }
160-
161- public bool Cancel ( )
112+ if ( cancellationToken . IsCancellationRequested )
162113 {
163- return this . promise . TrySetCanceled ( ) ;
114+ return TaskEx . Cancelled ;
164115 }
165116
166- public Task Completion
117+ if ( ! cancellationToken . CanBeCanceled )
167118 {
168- get { return this . promise . Task ; }
119+ return this . Schedule ( action , delay ) . Completion ;
169120 }
170121
171- public CancellationToken CancellationToken { get ; private set ; }
172-
173- int IComparable < IScheduledRunnable > . CompareTo ( IScheduledRunnable other )
174- {
175- Contract . Requires ( other != null ) ;
176-
177- return this . Deadline . CompareTo ( other . Deadline ) ;
178- }
122+ return this . Schedule ( new ActionScheduledAsyncTask ( this , action , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ) . Completion ;
123+ }
179124
180- public override IRunnable Value
125+ public override Task ScheduleAsync ( Action < object > action , object state , TimeSpan delay , CancellationToken cancellationToken )
126+ {
127+ if ( cancellationToken . IsCancellationRequested )
181128 {
182- get { return this ; }
129+ return TaskEx . Cancelled ;
183130 }
184131
185- public void Run ( )
132+ if ( ! cancellationToken . CanBeCanceled )
186133 {
187- if ( this . CancellationToken . IsCancellationRequested )
188- {
189- this . promise . TrySetCanceled ( ) ;
190- return ;
191- }
192- if ( this . Completion . IsCanceled )
193- {
194- return ;
195- }
196- try
197- {
198- this . Execute ( ) ;
199- this . promise . TryComplete ( ) ;
200- }
201- catch ( Exception ex )
202- {
203- // todo: check for fatal
204- this . promise . TrySetException ( ex ) ;
205- }
134+ return this . Schedule ( action , state , delay ) . Completion ;
206135 }
207136
208- protected abstract void Execute ( ) ;
137+ return this . Schedule ( new StateActionScheduledAsyncTask ( this , action , state , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ) . Completion ;
209138 }
210139
211- sealed class ActionScheduledTask : ScheduledTaskBase
140+ public override Task ScheduleAsync ( Action < object , object > action , object context , object state , TimeSpan delay , CancellationToken cancellationToken )
212141 {
213- readonly Action action ;
214-
215- public ActionScheduledTask ( Action action , PreciseTimeSpan deadline , CancellationToken cancellationToken )
216- : base ( deadline , new TaskCompletionSource ( ) , cancellationToken )
142+ if ( cancellationToken . IsCancellationRequested )
217143 {
218- this . action = action ;
144+ return TaskEx . Cancelled ;
219145 }
220146
221- protected override void Execute ( )
147+ if ( ! cancellationToken . CanBeCanceled )
222148 {
223- this . action ( ) ;
149+ return this . Schedule ( action , context , state , delay ) . Completion ;
224150 }
151+
152+ return this . Schedule ( new StateActionWithContextScheduledAsyncTask ( this , action , context , state , PreciseTimeSpan . Deadline ( delay ) , cancellationToken ) ) . Completion ;
225153 }
226154
227- sealed class StateActionScheduledTask : ScheduledTaskBase
155+ protected IScheduledRunnable Schedule ( IScheduledRunnable task )
228156 {
229- readonly Action < object > action ;
230-
231- public StateActionScheduledTask ( Action < object > action , object state , PreciseTimeSpan deadline ,
232- CancellationToken cancellationToken )
233- : base ( deadline , new TaskCompletionSource ( state ) , cancellationToken )
157+ if ( this . InEventLoop )
234158 {
235- this . action = action ;
159+ this . ScheduledTaskQueue . Enqueue ( task ) ;
236160 }
237-
238- protected override void Execute ( )
161+ else
239162 {
240- this . action ( this . Completion . AsyncState ) ;
163+ this . Execute ( ( e , t ) => ( ( AbstractScheduledEventExecutor ) e ) . ScheduledTaskQueue . Enqueue ( ( IScheduledRunnable ) t ) , this , task ) ;
241164 }
165+ return task ;
242166 }
243167
244- sealed class StateActionWithContextScheduledTask : ScheduledTaskBase
168+ internal void RemoveScheduled ( IScheduledRunnable task )
245169 {
246- readonly Action < object , object > action ;
247- readonly object context ;
248-
249- public StateActionWithContextScheduledTask ( Action < object , object > action , object context , object state ,
250- PreciseTimeSpan deadline , CancellationToken cancellationToken )
251- : base ( deadline , new TaskCompletionSource ( state ) , cancellationToken )
170+ if ( this . InEventLoop )
252171 {
253- this . action = action ;
254- this . context = context ;
172+ this . ScheduledTaskQueue . Remove ( task ) ;
255173 }
256-
257- protected override void Execute ( )
174+ else
258175 {
259- this . action ( this . context , this . Completion . AsyncState ) ;
176+ this . Execute ( ( e , t ) => ( ( AbstractScheduledEventExecutor ) e ) . ScheduledTaskQueue . Remove ( ( IScheduledRunnable ) t ) , this , task ) ;
260177 }
261178 }
262-
263- #endregion
264179 }
265180}
0 commit comments