Skip to content

Commit 1fb5f4d

Browse files
committed
Merge pull request #107 from nayato/schedule-runnable
Adds Schedule support for IRunnable actions.
2 parents c23becf + 28f6279 commit 1fb5f4d

8 files changed

Lines changed: 52 additions & 48 deletions

File tree

src/DotNetty.Common/Concurrency/AbstractEventExecutor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ public void Execute(Action action)
5252
this.Execute(new ActionTaskQueueNode(action));
5353
}
5454

55+
public virtual IScheduledTask Schedule(IRunnable action, TimeSpan delay)
56+
{
57+
throw new NotSupportedException();
58+
}
59+
5560
public virtual IScheduledTask Schedule(Action action, TimeSpan delay)
5661
{
5762
throw new NotSupportedException();

src/DotNetty.Common/Concurrency/AbstractScheduledEventExecutor.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,38 @@ protected bool HasScheduledTasks()
9292
return scheduledTask != null && scheduledTask.Deadline <= PreciseTimeSpan.FromStart;
9393
}
9494

95+
public override IScheduledTask Schedule(IRunnable action, TimeSpan delay)
96+
{
97+
Contract.Requires(action != null);
98+
99+
return this.Schedule(new RunnableScheduledTask(this, action, PreciseTimeSpan.Deadline(delay)));
100+
}
101+
95102
public override IScheduledTask Schedule(Action action, TimeSpan delay)
96103
{
104+
Contract.Requires(action != null);
105+
97106
return this.Schedule(new ActionScheduledTask(this, action, PreciseTimeSpan.Deadline(delay)));
98107
}
99108

100109
public override IScheduledTask Schedule(Action<object> action, object state, TimeSpan delay)
101110
{
111+
Contract.Requires(action != null);
112+
102113
return this.Schedule(new StateActionScheduledTask(this, action, state, PreciseTimeSpan.Deadline(delay)));
103114
}
104115

105116
public override IScheduledTask Schedule(Action<object, object> action, object context, object state, TimeSpan delay)
106117
{
118+
Contract.Requires(action != null);
119+
107120
return this.Schedule(new StateActionWithContextScheduledTask(this, action, context, state, PreciseTimeSpan.Deadline(delay)));
108121
}
109122

110123
public override Task ScheduleAsync(Action action, TimeSpan delay, CancellationToken cancellationToken)
111124
{
125+
Contract.Requires(action != null);
126+
112127
if (cancellationToken.IsCancellationRequested)
113128
{
114129
return TaskEx.Cancelled;

src/DotNetty.Common/Concurrency/IEventExecutor.cs

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ public interface IEventExecutor
3838
/// Returns <c>true</c> if all tasks have completed following shut down.
3939
/// </summary>
4040
/// <remarks>
41-
/// Note that <see cref="IsTerminated" /> is never <c>true</c> unless either <see cref="ShutdownGracefullyAsync()" />
42-
/// or <see cref="ShutdownNow()" /> was called first.
41+
/// Note that <see cref="IsTerminated" /> is never <c>true</c> unless <see cref="ShutdownGracefullyAsync()" /> was called first.
4342
/// </remarks>
4443
bool IsTerminated { get; }
4544

@@ -49,33 +48,6 @@ public interface IEventExecutor
4948
/// </summary>
5049
bool IsInEventLoop(Thread thread);
5150

52-
/// <summary>
53-
/// Returns an <see cref="IEventExecutor" /> that is not an <see cref="IWrappedEventExecutor" />.
54-
/// </summary>
55-
/// <remarks>
56-
/// <list type="bullet">
57-
/// <item>
58-
/// <description>
59-
/// A <see cref="IWrappedEventExecutor" /> implementing this method must return the underlying
60-
/// <see cref="IEventExecutor" /> while making sure that it's not a <see cref="IWrappedEventExecutor" />
61-
/// (e.g. by multiple calls to <see cref="Unwrap()" />).
62-
/// </description>
63-
/// </item>
64-
/// <item>
65-
/// <description>
66-
/// An <see cref="IEventExecutor" /> that is not a <see cref="IWrappedEventExecutor" /> must return a
67-
/// reference to itself.
68-
/// </description>
69-
/// </item>
70-
/// <item>
71-
/// <description>
72-
/// This method must not return null.
73-
/// </description>
74-
/// </item>
75-
/// </list>
76-
/// </remarks>
77-
IEventExecutor Unwrap();
78-
7951
/// <summary>
8052
/// Executes the given task.
8153
/// </summary>
@@ -108,6 +80,14 @@ public interface IEventExecutor
10880
/// </remarks>
10981
void Execute(Action<object, object> action, object context, object state);
11082

83+
/// <summary>
84+
/// Creates and executes a one-shot action that becomes enabled after the given delay.
85+
/// </summary>
86+
/// <param name="action">the task to execute</param>
87+
/// <param name="delay">the time from now to delay execution</param>
88+
/// <returns>an <see cref="IScheduledTask" /> representing pending completion of the task.</returns>
89+
IScheduledTask Schedule(IRunnable action, TimeSpan delay);
90+
11191
/// <summary>
11292
/// Schedules the given action for execution after the specified delay would pass.
11393
/// </summary>

src/DotNetty.Common/Concurrency/IWrappedEventExecutor.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace DotNetty.Common.Concurrency
5+
{
6+
sealed class RunnableScheduledTask : ScheduledTask
7+
{
8+
readonly IRunnable action;
9+
10+
public RunnableScheduledTask(AbstractScheduledEventExecutor executor, IRunnable action, PreciseTimeSpan deadline)
11+
: base(executor, deadline, new TaskCompletionSource())
12+
{
13+
this.action = action;
14+
}
15+
16+
protected override void Execute() => this.action.Run();
17+
}
18+
}

src/DotNetty.Common/DotNetty.Common.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
<Compile Include="Concurrency\ICallable`T.cs" />
155155
<Compile Include="Concurrency\IScheduledRunnable.cs" />
156156
<Compile Include="Concurrency\IScheduledTask.cs" />
157+
<Compile Include="Concurrency\RunnableScheduledTask.cs" />
157158
<Compile Include="Concurrency\ScheduledAsyncTask.cs" />
158159
<Compile Include="Concurrency\ScheduledTask.cs" />
159160
<Compile Include="Concurrency\StateActionScheduledAsyncTask.cs" />
@@ -175,7 +176,6 @@
175176
<Compile Include="Concurrency\ExecutorTaskScheduler.cs" />
176177
<Compile Include="Concurrency\IEventExecutor.cs" />
177178
<Compile Include="Concurrency\IRunnable.cs" />
178-
<Compile Include="Concurrency\IWrappedEventExecutor.cs" />
179179
<Compile Include="Concurrency\SingleThreadEventExecutor.cs" />
180180
<Compile Include="Concurrency\TaskCompletionSource.cs" />
181181
<Compile Include="Internal\Logging\AbstractInternalLogger.cs" />

src/DotNetty.Transport/Channels/DefaultChannelPipeline.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ IChannelHandler Replace(AbstractChannelHandlerContext ctx, string newName, IChan
473473
IEventExecutor executor;
474474
bool inEventLoop;
475475

476-
lock (this.head)
476+
lock (this)
477477
{
478478
CheckMultiplicity(newHandler);
479479

@@ -788,7 +788,7 @@ void DestroyUp(AbstractChannelHandlerContext ctx, bool inEventLoop)
788788
IEventExecutor executor = ctx.Executor;
789789
if (!inEventLoop && !executor.IsInEventLoop(currentThread))
790790
{
791-
executor.Unwrap().Execute((self, c) => ((DefaultChannelPipeline)self).DestroyUp((AbstractChannelHandlerContext)c, true), this, ctx);
791+
executor.Execute((self, c) => ((DefaultChannelPipeline)self).DestroyUp((AbstractChannelHandlerContext)c, true), this, ctx);
792792
break;
793793
}
794794

@@ -811,15 +811,15 @@ void DestroyDown(Thread currentThread, AbstractChannelHandlerContext ctx, bool i
811811
IEventExecutor executor = ctx.Executor;
812812
if (inEventLoop || executor.IsInEventLoop(currentThread))
813813
{
814-
lock (this.head)
814+
lock (this)
815815
{
816816
Remove0(ctx);
817817
this.CallHandlerRemoved0(ctx);
818818
}
819819
}
820820
else
821821
{
822-
executor.Unwrap().Execute((self, c) => ((DefaultChannelPipeline)self).DestroyDown(Thread.CurrentThread, (AbstractChannelHandlerContext)c, true), this, ctx);
822+
executor.Execute((self, c) => ((DefaultChannelPipeline)self).DestroyDown(Thread.CurrentThread, (AbstractChannelHandlerContext)c, true), this, ctx);
823823
break;
824824
}
825825

src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public override bool IsInEventLoop(Thread thread)
4040
return true;
4141
}
4242

43-
IEventExecutor IEventExecutor.Unwrap()
44-
{
45-
return this.Unwrap();
46-
}
47-
4843
public override void Execute(IRunnable command)
4944
{
5045
if (command == null)

0 commit comments

Comments
 (0)