Convert javadoc to C# xmldoc in the DotNetty.Transport project (#389)

This is a progressive commit towards completing #386.

No code changes have been made, only changes to comments.

These changes to comments include:
- Transforming {@link Symbol} occurrences to <see cref="Symbol"/>
- Updating Java example code in comments with C# equivalents
- Translating/removing comments that do not apply to .NET generally
- Removing Netty-specific comments that do not yet apply to this port
- Various grammar and typo corrections
This commit is contained in:
gmacster 2018-04-06 13:24:40 -04:00 коммит произвёл Max Gortman
Родитель 2cd04cd8a7
Коммит 997e60f19b
34 изменённых файлов: 1274 добавлений и 1093 удалений

Просмотреть файл

@ -16,12 +16,11 @@ namespace DotNetty.Transport.Bootstrapping
using DotNetty.Transport.Channels;
/// <summary>
/// {@link AbstractBootstrap} is a helper class that makes it easy to bootstrap a {@link Channel}. It support
/// method-chaining to provide an easy way to configure the {@link AbstractBootstrap}.
/// <p>
/// When not used in a {@link ServerBootstrap} context, the {@link #bind()} methods are useful for connectionless
/// transports such as datagram (UDP).
/// </p>
/// This is a helper class that makes it easy to bootstrap an <see cref="IChannel"/>. It supports method-
/// chaining to provide an easy way to configure the <see cref="AbstractBootstrap{TBootstrap,TChannel}"/>.
///
/// When not used in a <see cref="ServerBootstrap"/> context, the <see cref="BindAsync(EndPoint)"/> methods
/// are useful for connectionless transports such as datagram (UDP).
/// </summary>
public abstract class AbstractBootstrap<TBootstrap, TChannel>
where TBootstrap : AbstractBootstrap<TBootstrap, TChannel>
@ -54,9 +53,10 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// The {@link EventLoopGroup} which is used to handle all the events for the to-be-created
/// {@link Channel}
/// Specifies the <see cref="IEventLoopGroup"/> which will handle events for the <see cref="IChannel"/> being built.
/// </summary>
/// <param name="group">The <see cref="IEventLoopGroup"/> which is used to handle all the events for the to-be-created <see cref="IChannel"/>.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public virtual TBootstrap Group(IEventLoopGroup group)
{
Contract.Requires(group != null);
@ -70,12 +70,11 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// The {@link Class} which is used to create {@link Channel} instances from.
/// You either use this or {@link #channelFactory(io.netty.channel.ChannelFactory)} if your
/// {@link Channel} implementation has no no-args constructor.
/// Specifies the <see cref="Type"/> of <see cref="IChannel"/> which will be created.
/// </summary>
public TBootstrap Channel<T>()
where T : TChannel, new() => this.ChannelFactory(() => new T());
/// <typeparam name="T">The <see cref="Type"/> which is used to create <see cref="IChannel"/> instances from.</typeparam>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap Channel<T>() where T : TChannel, new() => this.ChannelFactory(() => new T());
public TBootstrap ChannelFactory(Func<TChannel> channelFactory)
{
@ -85,8 +84,10 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// The {@link SocketAddress} which is used to bind the local "end" to.
/// Assigns the <see cref="EndPoint"/> which is used to bind the local "end" to.
/// </summary>
/// <param name="localAddress">The <see cref="EndPoint"/> instance to bind the local "end" to.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap LocalAddress(EndPoint localAddress)
{
this.localAddress = localAddress;
@ -94,24 +95,38 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// @see {@link #localAddress(SocketAddress)}
/// Assigns the local <see cref="EndPoint"/> which is used to bind the local "end" to.
/// This overload binds to a <see cref="IPEndPoint"/> for any IP address on the local machine, given a specific port.
/// </summary>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap LocalAddress(int inetPort) => this.LocalAddress(new IPEndPoint(IPAddress.Any, inetPort));
/// <summary>
/// @see {@link #localAddress(SocketAddress)}
/// Assigns the local <see cref="EndPoint"/> which is used to bind the local "end" to.
/// This overload binds to a <see cref="DnsEndPoint"/> for a given hostname and port.
/// </summary>
/// <param name="inetHost">The hostname to bind the local "end" to.</param>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap LocalAddress(string inetHost, int inetPort) => this.LocalAddress(new DnsEndPoint(inetHost, inetPort));
/// <summary>
/// @see {@link #localAddress(SocketAddress)}
/// Assigns the local <see cref="EndPoint"/> which is used to bind the local "end" to.
/// This overload binds to a <see cref="IPEndPoint"/> for a given <see cref="IPAddress"/> and port.
/// </summary>
/// <param name="inetHost">The <see cref="IPAddress"/> to bind the local "end" to.</param>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap LocalAddress(IPAddress inetHost, int inetPort) => this.LocalAddress(new IPEndPoint(inetHost, inetPort));
/// <summary>
/// Allow to specify a {@link ChannelOption} which is used for the {@link Channel} instances once they got
/// created. Use a value of {@code null} to remove a previous set {@link ChannelOption}.
/// Allows the specification of a <see cref="ChannelOption{T}"/> which is used for the
/// <see cref="IChannel"/> instances once they get created. Use a value of <c>null</c> to remove
/// a previously set <see cref="ChannelOption{T}"/>.
/// </summary>
/// <param name="option">The <see cref="ChannelOption{T}"/> to configure.</param>
/// <param name="value">The value to set the given option.</param>
public TBootstrap Option<T>(ChannelOption<T> option, T value)
{
Contract.Requires(option != null);
@ -129,8 +144,8 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Allow to specify an initial attribute of the newly created <see cref="IChannel" /> . If the <c>value</c> is
/// <c>null</c>, the attribute of the specified <c>key</c> is removed.
/// Allows specification of an initial attribute of the newly created <see cref="IChannel" />. If the <c>value</c> is
/// <c>null</c>, the attribute of the specified <c>key</c> is removed.
/// </summary>
public TBootstrap Attribute<T>(AttributeKey<T> key, T value)
where T : class
@ -150,12 +165,7 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Allow to specify an initial attribute of the newly created {@link Channel}. If the {@code value} is
/// {@code null}, the attribute of the specified {@code key} is removed.
/// </summary>
/// <summary>
/// Validate all the parameters. Sub-classes may override this, but should
/// call the super method in that case.
/// Validates all the parameters. Sub-classes may override this, but should call the super method in that case.
/// </summary>
public virtual TBootstrap Validate()
{
@ -171,14 +181,14 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Returns a deep clone of this bootstrap which has the identical configuration. This method is useful when making
/// multiple {@link Channel}s with similar settings. Please note that this method does not clone the
/// {@link EventLoopGroup} deeply but shallowly, making the group a shared resource.
/// Returns a deep clone of this bootstrap which has the identical configuration. This method is useful when making
/// multiple <see cref="IChannel"/>s with similar settings. Please note that this method does not clone the
/// <see cref="IEventLoopGroup"/> deeply but shallowly, making the group a shared resource.
/// </summary>
public abstract TBootstrap Clone();
/// <summary>
/// Create a new {@link Channel} and register it with an {@link EventLoop}.
/// Creates a new <see cref="IChannel"/> and registers it with an <see cref="IEventLoop"/>.
/// </summary>
public Task RegisterAsync()
{
@ -187,8 +197,9 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Create a new {@link Channel} and bind it.
/// Creates a new <see cref="IChannel"/> and binds it to the endpoint specified via the <see cref="LocalAddress(EndPoint)"/> methods.
/// </summary>
/// <returns>The bound <see cref="IChannel"/>.</returns>
public Task<IChannel> BindAsync()
{
this.Validate();
@ -201,23 +212,36 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Create a new {@link Channel} and bind it.
/// Creates a new <see cref="IChannel"/> and binds it.
/// This overload binds to a <see cref="IPEndPoint"/> for any IP address on the local machine, given a specific port.
/// </summary>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The bound <see cref="IChannel"/>.</returns>
public Task<IChannel> BindAsync(int inetPort) => this.BindAsync(new IPEndPoint(IPAddress.Any, inetPort));
/// <summary>
/// Create a new {@link Channel} and bind it.
/// Creates a new <see cref="IChannel"/> and binds it.
/// This overload binds to a <see cref="DnsEndPoint"/> for a given hostname and port.
/// </summary>
/// <param name="inetHost">The hostname to bind the local "end" to.</param>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The bound <see cref="IChannel"/>.</returns>
public Task<IChannel> BindAsync(string inetHost, int inetPort) => this.BindAsync(new DnsEndPoint(inetHost, inetPort));
/// <summary>
/// Create a new {@link Channel} and bind it.
/// Creates a new <see cref="IChannel"/> and binds it.
/// This overload binds to a <see cref="IPEndPoint"/> for a given <see cref="IPAddress"/> and port.
/// </summary>
/// <param name="inetHost">The <see cref="IPAddress"/> to bind the local "end" to.</param>
/// <param name="inetPort">The port to bind the local "end" to.</param>
/// <returns>The bound <see cref="IChannel"/>.</returns>
public Task<IChannel> BindAsync(IPAddress inetHost, int inetPort) => this.BindAsync(new IPEndPoint(inetHost, inetPort));
/// <summary>
/// Create a new {@link Channel} and bind it.
/// Creates a new <see cref="IChannel"/> and binds it.
/// </summary>
/// <param name="localAddress">The <see cref="EndPoint"/> instance to bind the local "end" to.</param>
/// <returns>The bound <see cref="IChannel"/>.</returns>
public Task<IChannel> BindAsync(EndPoint localAddress)
{
this.Validate();
@ -307,8 +331,10 @@ namespace DotNetty.Transport.Bootstrapping
protected abstract void Init(IChannel channel);
/// <summary>
/// the {@link ChannelHandler} to use for serving the requests.
/// Specifies the <see cref="IChannelHandler"/> to use for serving the requests.
/// </summary>
/// <param name="handler">The <see cref="IChannelHandler"/> to use for serving requests.</param>
/// <returns>The <see cref="AbstractBootstrap{TBootstrap,TChannel}"/> instance.</returns>
public TBootstrap Handler(IChannelHandler handler)
{
Contract.Requires(handler != null);
@ -321,7 +347,7 @@ namespace DotNetty.Transport.Bootstrapping
protected IChannelHandler Handler() => this.handler;
/// <summary>
/// Return the configured {@link EventLoopGroup} or {@code null} if non is configured yet.
/// Returns the configured <see cref="IEventLoopGroup"/> or <c>null</c> if none is configured yet.
/// </summary>
public IEventLoopGroup Group() => this.group;

Просмотреть файл

@ -15,12 +15,11 @@ namespace DotNetty.Transport.Bootstrapping
using DotNetty.Transport.Channels;
/// <summary>
/// A {@link Bootstrap} that makes it easy to bootstrap a {@link Channel} to use
/// for clients.
/// <p>
/// The {@link #bind()} methods are useful in combination with connectionless transports such as datagram (UDP).
/// For regular TCP connections, please use the provided {@link #connect()} methods.
/// </p>
/// A <see cref="Bootstrap"/> that makes it easy to bootstrap an <see cref="IChannel"/> to use for clients.
///
/// The <see cref="AbstractBootstrap{TBootstrap,TChannel}.BindAsync(EndPoint)"/> methods are useful
/// in combination with connectionless transports such as datagram (UDP). For regular TCP connections,
/// please use the provided <see cref="ConnectAsync(EndPoint,EndPoint)"/> methods.
/// </summary>
public class Bootstrap : AbstractBootstrap<Bootstrap, IChannel>
{
@ -43,8 +42,10 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Sets the {@link NameResolver} which will resolve the address of the unresolved named address.
/// Sets the <see cref="INameResolver"/> which will resolve the address of the unresolved named address.
/// </summary>
/// <param name="resolver">The <see cref="INameResolver"/> which will resolve the address of the unresolved named address.</param>
/// <returns>The <see cref="Bootstrap"/> instance.</returns>
public Bootstrap Resolver(INameResolver resolver)
{
Contract.Requires(resolver != null);
@ -53,9 +54,10 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// The {@link SocketAddress} to connect to once the {@link #connect()} method
/// is called.
/// Assigns the remote <see cref="EndPoint"/> to connect to once the <see cref="ConnectAsync()"/> method is called.
/// </summary>
/// <param name="remoteAddress">The remote <see cref="EndPoint"/> to connect to.</param>
/// <returns>The <see cref="Bootstrap"/> instance.</returns>
public Bootstrap RemoteAddress(EndPoint remoteAddress)
{
this.remoteAddress = remoteAddress;
@ -63,8 +65,11 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// @see {@link #remoteAddress(SocketAddress)}
/// Assigns the remote <see cref="EndPoint"/> to connect to once the <see cref="ConnectAsync()"/> method is called.
/// </summary>
/// <param name="inetHost">The hostname of the endpoint to connect to.</param>
/// <param name="inetPort">The port at the remote host to connect to.</param>
/// <returns>The <see cref="Bootstrap"/> instance.</returns>
public Bootstrap RemoteAddress(string inetHost, int inetPort)
{
this.remoteAddress = new DnsEndPoint(inetHost, inetPort);
@ -72,8 +77,11 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// @see {@link #remoteAddress(SocketAddress)}
/// Assigns the remote <see cref="EndPoint"/> to connect to once the <see cref="ConnectAsync()"/> method is called.
/// </summary>
/// <param name="inetHost">The <see cref="IPAddress"/> of the endpoint to connect to.</param>
/// <param name="inetPort">The port at the remote host to connect to.</param>
/// <returns>The <see cref="Bootstrap"/> instance.</returns>
public Bootstrap RemoteAddress(IPAddress inetHost, int inetPort)
{
this.remoteAddress = new IPEndPoint(inetHost, inetPort);
@ -81,8 +89,9 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Connect a {@link Channel} to the remote peer.
/// Connects an <see cref="IChannel"/> to the remote peer.
/// </summary>
/// <returns>The <see cref="IChannel"/>.</returns>
public Task<IChannel> ConnectAsync()
{
this.Validate();
@ -96,18 +105,26 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Connect a {@link Channel} to the remote peer.
/// Connects an <see cref="IChannel"/> to the remote peer.
/// </summary>
/// <param name="inetHost">The hostname of the endpoint to connect to.</param>
/// <param name="inetPort">The port at the remote host to connect to.</param>
/// <returns>The <see cref="IChannel"/>.</returns>
public Task<IChannel> ConnectAsync(string inetHost, int inetPort) => this.ConnectAsync(new DnsEndPoint(inetHost, inetPort));
/// <summary>
/// Connect a {@link Channel} to the remote peer.
/// Connects an <see cref="IChannel"/> to the remote peer.
/// </summary>
/// <param name="inetHost">The <see cref="IPAddress"/> of the endpoint to connect to.</param>
/// <param name="inetPort">The port at the remote host to connect to.</param>
/// <returns>The <see cref="IChannel"/>.</returns>
public Task<IChannel> ConnectAsync(IPAddress inetHost, int inetPort) => this.ConnectAsync(new IPEndPoint(inetHost, inetPort));
/// <summary>
/// Connect a {@link Channel} to the remote peer.
/// Connects an <see cref="IChannel"/> to the remote peer.
/// </summary>
/// <param name="remoteAddress">The remote <see cref="EndPoint"/> to connect to.</param>
/// <returns>The <see cref="IChannel"/>.</returns>
public Task<IChannel> ConnectAsync(EndPoint remoteAddress)
{
Contract.Requires(remoteAddress != null);
@ -117,8 +134,11 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Connect a {@link Channel} to the remote peer.
/// Connects an <see cref="IChannel"/> to the remote peer.
/// </summary>
/// <param name="remoteAddress">The remote <see cref="EndPoint"/> to connect to.</param>
/// <param name="localAddress">The local <see cref="EndPoint"/> to connect to.</param>
/// <returns>The <see cref="IChannel"/>.</returns>
public Task<IChannel> ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
{
Contract.Requires(remoteAddress != null);
@ -128,8 +148,11 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// @see {@link #connect()}
/// Performs DNS resolution for the remote endpoint and connects to it.
/// </summary>
/// <param name="remoteAddress">The remote <see cref="EndPoint"/> to connect to.</param>
/// <param name="localAddress">The local <see cref="EndPoint"/> to connect the remote to.</param>
/// <returns>The <see cref="IChannel"/>.</returns>
async Task<IChannel> DoResolveAndConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
{
IChannel channel = await this.InitAndRegisterAsync();
@ -220,9 +243,9 @@ namespace DotNetty.Transport.Bootstrapping
public override Bootstrap Clone() => new Bootstrap(this);
/// <summary>
/// Returns a deep clone of this bootstrap which has the identical configuration except that it uses
/// the given {@link EventLoopGroup}. This method is useful when making multiple {@link Channel}s with similar
/// settings.
/// Returns a deep clone of this bootstrap which has the identical configuration except that it uses
/// the given <see cref="IEventLoopGroup"/>. This method is useful when making multiple <see cref="IChannel"/>s with similar
/// settings.
/// </summary>
public Bootstrap Clone(IEventLoopGroup group)
{

Просмотреть файл

@ -14,7 +14,7 @@ namespace DotNetty.Transport.Bootstrapping
using DotNetty.Transport.Channels;
/// <summary>
/// {@link Bootstrap} sub-class which allows easy bootstrap of {@link ServerChannel}
/// A <see cref="Bootstrap"/> sub-class which allows easy bootstrapping of <see cref="IServerChannel"/>.
/// </summary>
public class ServerBootstrap : AbstractBootstrap<ServerBootstrap, IServerChannel>
{
@ -41,14 +41,14 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Specify the {@link EventLoopGroup} which is used for the parent (acceptor) and the child (client).
/// Specifies the <see cref="IEventLoopGroup"/> which is used for the parent (acceptor) and the child (client).
/// </summary>
public override ServerBootstrap Group(IEventLoopGroup group) => this.Group(group, group);
/// <summary>
/// Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
/// {@link EventLoopGroup}'s are used to handle all the events and IO for {@link ServerChannel} and
/// {@link Channel}'s.
/// Sets the <see cref="IEventLoopGroup"/> for the parent (acceptor) and the child (client). These
/// <see cref="IEventLoopGroup"/>'s are used to handle all the events and IO for <see cref="IServerChannel"/>
/// and <see cref="IChannel"/>'s.
/// </summary>
public ServerBootstrap Group(IEventLoopGroup parentGroup, IEventLoopGroup childGroup)
{
@ -64,9 +64,9 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Allow to specify a {@link ChannelOption} which is used for the {@link Channel} instances once they get created
/// (after the acceptor accepted the {@link Channel}). Use a value of {@code null} to remove a previous set
/// {@link ChannelOption}.
/// Allows specification of a <see cref="ChannelOption"/> which is used for the <see cref="IChannel"/>
/// instances once they get created (after the acceptor accepted the <see cref="IChannel"/>). Use a
/// value of <c>null</c> to remove a previously set <see cref="ChannelOption"/>.
/// </summary>
public ServerBootstrap ChildOption<T>(ChannelOption<T> childOption, T value)
{
@ -85,8 +85,8 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Set the specific {@link AttributeKey} with the given value on every child {@link Channel}. If the value is
/// {@code null} the {@link AttributeKey} is removed
/// Sets the specific <see cref="AttributeKey{T}"/> with the given value on every child <see cref="IChannel"/>.
/// If the value is <c>null</c>, the <see cref="AttributeKey{T}"/> is removed.
/// </summary>
public ServerBootstrap ChildAttribute<T>(AttributeKey<T> childKey, T value)
where T : class
@ -106,7 +106,7 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Set the {@link ChannelHandler} which is used to serve the request for the {@link Channel}'s.
/// Sets the <see cref="IChannelHandler"/> which is used to serve the request for the <see cref="IChannel"/>'s.
/// </summary>
public ServerBootstrap ChildHandler(IChannelHandler childHandler)
{
@ -117,8 +117,8 @@ namespace DotNetty.Transport.Bootstrapping
}
/// <summary>
/// Return the configured {@link EventLoopGroup} which will be used for the child channels or {@code null}
/// if non is configured yet.
/// Returns the configured <see cref="IEventLoopGroup"/> which will be used for the child channels or <c>null</c>
/// if none is configured yet.
/// </summary>
public IEventLoopGroup ChildGroup() => this.childGroup;

Просмотреть файл

@ -36,9 +36,9 @@ namespace DotNetty.Transport.Channels
string strVal;
/// <summary>
/// Creates a new instance.
/// Creates a new instance.
/// </summary>
/// <param name="parent">the parent of this channel. <c>null</c> if there's no parent.</param>
/// <param name="parent">The parent of this channel. Pass <c>null</c> if there's no parent.</param>
protected AbstractChannel(IChannel parent)
{
this.Parent = parent;
@ -48,9 +48,10 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Creates a new instance.
/// Creates a new instance.
/// </summary>
/// <param name="parent">the parent of this channel. <c>null</c> if there's no parent.</param>
/// <param name="parent">The parent of this channel. Pass <c>null</c> if there's no parent.</param>
/// <param name="id">An <see cref="IChannelId"/> for the new channel.</param>
protected AbstractChannel(IChannel parent, IChannelId id)
{
this.Parent = parent;
@ -134,6 +135,9 @@ namespace DotNetty.Transport.Channels
protected abstract EndPoint RemoteAddressInternal { get; }
/// <summary>
/// Resets the stored <see cref="RemoteAddress"/>.
/// </summary>
protected void InvalidateRemoteAddress() => this.remoteAddress = null;
protected EndPoint CacheRemoteAddress()
@ -149,13 +153,13 @@ namespace DotNetty.Transport.Channels
}
}
/// <summary>
/// Reset the stored remoteAddress
/// </summary>
public bool Registered => this.registered;
/// <summary>
/// Returns a new <see cref="DefaultChannelId"/> instance. Subclasses may override this method to assign custom
/// <see cref="IChannelId"/>s to <see cref="IChannel"/>s that use the <see cref="AbstractChannel"/> constructor.
/// </summary>
/// <returns>A new <see cref="DefaultChannelId"/> instance.</returns>
protected virtual IChannelId NewId() => DefaultChannelId.NewInstance();
/// <summary>Returns a new pipeline instance.</summary>
@ -194,29 +198,28 @@ namespace DotNetty.Transport.Channels
public IChannelUnsafe Unsafe => this.channelUnsafe;
/// <summary>
/// Create a new <see cref="AbstractUnsafe" /> instance which will be used for the life-time of the
/// <see cref="IChannel" />
/// Create a new <see cref="AbstractUnsafe" /> instance which will be used for the life-time of the
/// <see cref="IChannel" />
/// </summary>
protected abstract IChannelUnsafe NewUnsafe();
/// <summary>
/// Returns the ID of this channel.
/// Returns the ID of this channel.
/// </summary>
public override int GetHashCode() => this.Id.GetHashCode();
/// <summary>
/// Returns <c>true</c> if and only if the specified object is identical
/// with this channel (i.e. <c>this == o</c>).
/// Returns <c>true</c> if and only if the specified object is identical
/// with this channel (i.e. <c>this == o</c>).
/// </summary>
public override bool Equals(object o) => this == o;
public int CompareTo(IChannel o) => ReferenceEquals(this, o) ? 0 : this.Id.CompareTo(o.Id);
/// <summary>
/// Returns the string representation of this channel. The returned
/// string contains the {@linkplain #hashCode()} ID}, {@linkplain #localAddress() local address},
/// and {@linkplain #remoteAddress() remote address} of this channel for
/// easier identification.
/// Returns the string representation of this channel. The returned string contains a hex dump of the
/// <see cref="IChannelId"/>, the <see cref="LocalAddress"/>, and the <see cref="RemoteAddress"/> of this
/// channel for easier identification.
/// </summary>
public override string ToString()
{
@ -277,7 +280,7 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// <see cref="IChannelUnsafe" /> implementation which sub-classes must extend and use.
/// <see cref="IChannelUnsafe" /> implementation which sub-classes must extend and use.
/// </summary>
protected abstract class AbstractUnsafe : IChannelUnsafe
{
@ -579,11 +582,11 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// This method must NEVER be called directly, but be executed as an
/// extra task with a clean call stack instead. The reason for this
/// is that this method calls {@link ChannelPipeline#fireChannelUnregistered()}
/// directly, which might lead to an unfortunate nesting of independent inbound/outbound
/// events. See the comments input {@link #invokeLater(Runnable)} for more details.
/// This method must NEVER be called directly, but be executed as an
/// extra task with a clean call stack instead. The reason for this
/// is that this method calls <see cref="IChannelPipeline.FireChannelUnregistered"/>
/// directly, which might lead to an unfortunate nesting of independent inbound/outbound
/// events. See the comments input <see cref="InvokeLater"/> for more details.
/// </summary>
public Task DeregisterAsync()
{
@ -839,13 +842,18 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Return {@code true} if the given {@link EventLoop} is compatible with this instance.
/// Checks whether a given <see cref="IEventLoop"/> is compatible with the <see cref="AbstractChannel"/>.
/// </summary>
/// <param name="eventLoop">The <see cref="IEventLoop"/> to check compatibility.</param>
/// <returns>
/// <c>true</c> if the given <see cref="IEventLoop"/> is compatible with this <see cref="AbstractChannel"/>
/// instance, otherwise <c>false</c>.
/// </returns>
protected abstract bool IsCompatible(IEventLoop eventLoop);
/// <summary>
/// Is called after the {@link Channel} is registered with its {@link EventLoop} as part of the register process.
/// Sub-classes may override this method
/// Is called after the <see cref="IChannel"/> is registered with its <see cref="IEventLoop"/> as part of the
/// register process. Sub-classes may override this method.
/// </summary>
protected virtual void DoRegister()
{
@ -853,23 +861,24 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Bind the {@link Channel} to the {@link EndPoint}
/// Binds the <see cref="IChannel"/> to the <see cref="EndPoint"/>.
/// </summary>
/// <param name="localAddress">The <see cref="EndPoint"/> to bind.</param>
protected abstract void DoBind(EndPoint localAddress);
/// <summary>
/// Disconnect this {@link Channel} from its remote peer
/// Disconnects this <see cref="IChannel"/> from its remote peer.
/// </summary>
protected abstract void DoDisconnect();
/// <summary>
/// Close the {@link Channel}
/// Closes the <see cref="IChannel"/>.
/// </summary>
protected abstract void DoClose();
/// <summary>
/// Deregister the {@link Channel} from its {@link EventLoop}.
/// Sub-classes may override this method
/// Deregisters the <see cref="IChannel"/> from its <see cref="IEventLoop"/>. Sub-classes may override this
/// method.
/// </summary>
protected virtual void DoDeregister()
{
@ -877,19 +886,22 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// ScheduleAsync a read operation.
/// ScheduleAsync a read operation.
/// </summary>
protected abstract void DoBeginRead();
/// <summary>
/// Flush the content of the given buffer to the remote peer.
/// Flush the content of the given buffer to the remote peer.
/// </summary>
protected abstract void DoWrite(ChannelOutboundBuffer input);
/// <summary>
/// Invoked when a new message is added to a {@link ChannelOutboundBuffer} of this {@link AbstractChannel}, so that
/// the {@link Channel} implementation converts the message to another. (e.g. heap buffer -> direct buffer)
/// Invoked when a new message is added to a <see cref="ChannelOutboundBuffer"/> of this
/// <see cref="AbstractChannel"/>, so that the <see cref="IChannel"/> implementation converts the message to
/// another. (e.g. heap buffer -> direct buffer).
/// </summary>
/// <param name="msg">The message to be filtered.</param>
/// <returns>The filtered message.</returns>
protected virtual object FilterOutboundMessage(object msg) => msg;
}
}

Просмотреть файл

@ -8,24 +8,19 @@ namespace DotNetty.Transport.Channels
using System.Threading.Tasks;
using DotNetty.Common.Utilities;
/**
* A skeletal server-side {@link Channel} implementation. A server-side
* {@link Channel} does not allow the following operations:
* <ul>
* <li>{@link #connect(EndPoint, ChannelPromise)}</li>
* <li>{@link #disconnect(ChannelPromise)}</li>
* <li>{@link #write(Object, ChannelPromise)}</li>
* <li>{@link #flush()}</li>
* <li>and the shortcut methods which calls the methods mentioned above
* </ul>
*/
/// <summary>
/// A skeletal server-side <see cref="IChannel"/> implementation. A server-side <see cref="IChannel"/> does not
/// allow the following operations: <see cref="IChannel.ConnectAsync(EndPoint)"/>,
/// <see cref="IChannel.DisconnectAsync()"/>, <see cref="IChannel.WriteAsync(object)"/>,
/// <see cref="IChannel.Flush()"/>.
/// </summary>
public abstract class AbstractServerChannel : AbstractChannel, IServerChannel
{
static readonly ChannelMetadata METADATA = new ChannelMetadata(false, 16);
/**
* Creates a new instance.
*/
/// <summary>
/// Creates a new instance.
/// </summary>
protected AbstractServerChannel()
: base(null)
{

Просмотреть файл

@ -6,40 +6,43 @@ namespace DotNetty.Transport.Channels
using System;
using System.Collections.Concurrent;
using DotNetty.Common.Internal.Logging;
using DotNetty.Transport.Bootstrapping;
/// <summary>
/// A special {@link ChannelHandler} which offers an easy way to initialize a {@link Channel} once it was
/// registered to its {@link EventLoop}.
/// Implementations are most often used in the context of {@link Bootstrap#handler(ChannelHandler)} ,
/// {@link ServerBootstrap#handler(ChannelHandler)} and {@link ServerBootstrap#childHandler(ChannelHandler)} to
/// setup the {@link ChannelPipeline} of a {@link Channel}.
/// <pre>
/// public class MyChannelInitializer extends {@link ChannelInitializer} {
/// public void initChannel({@link Channel} channel) {
/// channel.pipeline().addLast("myHandler", new MyHandler());
/// }
/// }
/// {@link ServerBootstrap} bootstrap = ...;
/// ...
/// bootstrap.childHandler(new MyChannelInitializer());
/// ...
/// </pre>
/// Be aware that this class is marked as {@link Sharable} and so the implementation must be safe to be re-used.
/// @param <T> A sub-type of {@link Channel}
/// A special <see cref="IChannelHandler"/> which offers an easy way to initialize a <see cref="IChannel"/> once it was
/// registered to its <see cref="IEventLoop"/>.
/// <para>
/// Implementations are most often used in the context of <see cref="AbstractBootstrap{TBootstrap,TChannel}.Handler(IChannelHandler)"/>
/// and <see cref="ServerBootstrap.ChildHandler"/> to setup the <see cref="IChannelPipeline"/> of a <see cref="IChannel"/>.
/// </para>
/// Be aware that this class is marked as Sharable (via <see cref="IsSharable"/>) and so the implementation must be safe to be re-used.
/// </summary>
/// <example>
/// <code>
/// public class MyChannelInitializer extends <see cref="ChannelInitializer{T}"/> {
/// public void InitChannel(<see cref="IChannel"/> channel) {
/// channel.Pipeline().AddLast("myHandler", new MyHandler());
/// }
/// }
/// <see cref="ServerBootstrap"/> bootstrap = ...;
/// ...
/// bootstrap.childHandler(new MyChannelInitializer());
/// ...
/// </code>
/// </example>
/// <typeparam name="T">A sub-type of <see cref="IChannel"/>.</typeparam>
public abstract class ChannelInitializer<T> : ChannelHandlerAdapter
where T : IChannel
{
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<ChannelInitializer<T>>();
readonly ConcurrentDictionary<IChannelHandlerContext, bool> initMap = new ConcurrentDictionary<IChannelHandlerContext, bool>();
readonly ConcurrentDictionary<IChannelHandlerContext, bool> initMap = new ConcurrentDictionary<IChannelHandlerContext, bool>();
/// <summary>
/// This method will be called once the {@link Channel} was registered. After the method returns this instance
/// will be removed from the {@link ChannelPipeline} of the {@link Channel}.
/// @param channel the {@link Channel} which was registered.
/// @throws Exception is thrown if an error occurs. In that case the {@link Channel} will be closed.
/// This method will be called once the <see cref="IChannel"/> was registered. After the method returns this instance
/// will be removed from the <see cref="IChannelPipeline"/> of the <see cref="IChannel"/>.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> which was registered.</param>
protected abstract void InitChannel(T channel);
public override bool IsSharable => true;

Просмотреть файл

@ -19,18 +19,41 @@ namespace DotNetty.Transport.Channels
static readonly ChannelOptionPool Pool = new ChannelOptionPool();
/// <summary>Returns the {@link ChannelOption} of the specified name.</summary>
/// <summary>
/// Returns the <see cref="ChannelOption"/> of the specified name.
/// </summary>
/// <typeparam name="T">The type of option being retrieved.</typeparam>
/// <param name="name">The name of the desired option.</param>
/// <returns>The matching <see cref="ChannelOption{T}"/> instance.</returns>
public static ChannelOption<T> ValueOf<T>(string name) => (ChannelOption<T>)Pool.ValueOf<T>(name);
/// <summary>Shortcut of {@link #valueOf(String) valueOf(firstNameComponent.getName() + "#" + secondNameComponent)}.</summary>
/// <summary>
/// Returns the <see cref="ChannelOption{T}"/> of the given pair: (<see cref="Type"/>, secondary name)
/// </summary>
/// <typeparam name="T">The type of option being retrieved.</typeparam>
/// <param name="firstNameComponent">
/// A <see cref="Type"/> whose name will be used as the first part of the desired option's name.
/// </param>
/// <param name="secondNameComponent">
/// A string representing the second part of the desired option's name.
/// </param>
/// <returns>The matching <see cref="ChannelOption{T}"/> instance.</returns>
public static ChannelOption<T> ValueOf<T>(Type firstNameComponent, string secondNameComponent) => (ChannelOption<T>)Pool.ValueOf<T>(firstNameComponent, secondNameComponent);
/// <summary>Returns {@code true} if a {@link ChannelOption} exists for the given {@code name}.</summary>
/// <summary>
/// Checks whether a given <see cref="ChannelOption"/> exists.
/// </summary>
/// <param name="name">The name of the <see cref="ChannelOption"/>.</param>
/// <returns><c>true</c> if a <see cref="ChannelOption"/> exists for the given <paramref name="name"/>, otherwise <c>false</c>.</returns>
public static bool Exists(string name) => Pool.Exists(name);
/// <summary>Creates a new {@link ChannelOption} for the given {@code name} or fail with an
/// {@link IllegalArgumentException} if a {@link ChannelOption} for the given {@code name} exists.
/// <summary>
/// Creates a new <see cref="ChannelOption"/> for the given <paramref name="name"/>.
/// </summary>
/// <typeparam name="T">The type of option to create.</typeparam>
/// <param name="name">The name to associate with the new option.</param>
/// <exception cref="ArgumentException">Thrown if a <see cref="ChannelOption"/> for the given <paramref name="name"/> exists.</exception>
/// <returns>The new <see cref="ChannelOption{T}"/> instance.</returns>
public static ChannelOption<T> NewInstance<T>(string name) => (ChannelOption<T>)Pool.NewInstance<T>(name);
public static readonly ChannelOption<IByteBufferAllocator> Allocator = ValueOf<IByteBufferAllocator>("ALLOCATOR");

Просмотреть файл

@ -18,6 +18,7 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
using DotNetty.Transport.Channels.Sockets;
public sealed class ChannelOutboundBuffer
{
@ -52,9 +53,12 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Add given message to this {@link ChannelOutboundBuffer}. The given {@link ChannelPromise} will be notified once
/// the message was written.
/// Adds the given message to this <see cref="ChannelOutboundBuffer"/>. The given
/// <see cref="TaskCompletionSource"/> will be notified once the message was written.
/// </summary>
/// <param name="msg">The message to add to the buffer.</param>
/// <param name="size">The size of the message.</param>
/// <param name="promise">The <see cref="TaskCompletionSource"/> to notify once the message is written.</param>
public void AddMessage(object msg, int size, TaskCompletionSource promise)
{
Entry entry = Entry.NewInstance(msg, size, promise);
@ -80,8 +84,8 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Add a flush to this {@link ChannelOutboundBuffer}. This means all previous added messages are marked as flushed
/// and so you will be able to handle them.
/// Add a flush to this <see cref="ChannelOutboundBuffer"/>. This means all previous added messages are marked
/// as flushed and so you will be able to handle them.
/// </summary>
public void AddFlush()
{
@ -116,9 +120,10 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Increment the pending bytes which will be written at some point.
/// This method is thread-safe!
/// Increments the number of pending bytes which will be written at some point.
/// This method is thread-safe!
/// </summary>
/// <param name="size">The number of bytes to increment the count by.</param>
internal void IncrementPendingOutboundBytes(long size) => this.IncrementPendingOutboundBytes(size, true);
void IncrementPendingOutboundBytes(long size, bool invokeLater)
@ -136,9 +141,10 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Decrement the pending bytes which will be written at some point.
/// This method is thread-safe!
/// Decrements the number of pending bytes which will be written at some point.
/// This method is thread-safe!
/// </summary>
/// <param name="size">The number of bytes to decrement the count by.</param>
internal void DecrementPendingOutboundBytes(long size) => this.DecrementPendingOutboundBytes(size, true, true);
void DecrementPendingOutboundBytes(long size, bool invokeLater, bool notifyWritability)
@ -157,12 +163,13 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Return the current message to write or {@code null} if nothing was flushed before and so is ready to be written.
/// Returns the current message to write, or <c>null</c> if nothing was flushed before and so is ready to be
/// written.
/// </summary>
public object Current => this.flushedEntry?.Message;
/// <summary>
/// Notify the {@link ChannelPromise} of the current message about writing progress.
/// Notify the <see cref="TaskCompletionSource"/> of the current message about writing progress.
/// </summary>
public void Progress(long amount)
{
@ -179,10 +186,11 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Will remove the current message, mark its {@link ChannelPromise} as success and return {@code true}. If no
/// flushed message exists at the time this method is called it will return {@code false} to signal that no more
/// messages are ready to be handled.
/// Removes the current message, marks its <see cref="TaskCompletionSource"/> as complete, and returns
/// <c>true</c>. If no flushed message exists at the time this method is called, it returns <c>false</c> to
/// signal that no more messages are ready to be handled.
/// </summary>
/// <returns><c>true</c> if a message existed and was removed, otherwise <c>false</c>.</returns>
public bool Remove()
{
Entry e = this.flushedEntry;
@ -213,10 +221,12 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Will remove the current message, mark its {@link ChannelPromise} as failure using the given {@link Exception}
/// and return {@code true}. If no flushed message exists at the time this method is called it will return
/// {@code false} to signal that no more messages are ready to be handled.
/// Removes the current message, marks its <see cref="TaskCompletionSource"/> as complete using the given
/// <see cref="Exception"/>, and returns <c>true</c>. If no flushed message exists at the time this method is
/// called, it returns <c>false</c> to signal that no more messages are ready to be handled.
/// </summary>
/// <param name="cause">The <see cref="Exception"/> causing the message to be removed.</param>
/// <returns><c>true</c> if a message existed and was removed, otherwise <c>false</c>.</returns>
public bool Remove(Exception cause) => this.Remove0(cause, true);
bool Remove0(Exception cause, bool notifyWritability)
@ -267,9 +277,10 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Removes the fully written entries and update the reader index of the partially written entry.
/// This operation assumes all messages in this buffer is {@link ByteBuf}.
/// Removes the fully written entries and updates the reader index of the partially written entry.
/// This operation assumes all messages in this buffer are <see cref="IByteBuffer"/> instances.
/// </summary>
/// <param name="writtenBytes">The number of bytes that have been written so far.</param>
public void RemoveBytes(long writtenBytes)
{
while (true)
@ -307,36 +318,38 @@ namespace DotNetty.Transport.Channels
this.ClearNioBuffers();
}
// Clear all ByteBuffer from the array so these can be GC'ed.
// See https://github.com/netty/netty/issues/3837
/// <summary>
/// Clears all ByteBuffer from the array so these can be GC'ed.
/// See https://github.com/netty/netty/issues/3837
/// </summary>
void ClearNioBuffers() => NioBuffers.Value.Clear();
///
///Returns an array of direct NIO buffers if the currently pending messages are made of {@link ByteBuf} only.
///{@link #nioBufferCount()} and {@link #nioBufferSize()} will return the number of NIO buffers in the returned
///array and the total number of readable bytes of the NIO buffers respectively.
///<p>
///Note that the returned array is reused and thus should not escape
///{@link AbstractChannel#doWrite(ChannelOutboundBuffer)}.
///Refer to {@link NioSocketChannel#doWrite(ChannelOutboundBuffer)} for an example.
///</p>
///
/// <summary>
/// Returns a list of direct ArraySegment&lt;byte&gt;, if the currently pending messages are made of
/// <see cref="IByteBuffer"/> instances only. <see cref="NioBufferSize"/> will return the total number of
/// readable bytes of these buffers.
/// <para>
/// Note that the returned array is reused and thus should not escape
/// <see cref="AbstractChannel.DoWrite(ChannelOutboundBuffer)"/>. Refer to
/// <see cref="TcpSocketChannel.DoWrite(ChannelOutboundBuffer)"/> for an example.
/// </para>
/// </summary>
/// <returns>A list of ArraySegment&lt;byte&gt; buffers.</returns>
public List<ArraySegment<byte>> GetSharedBufferList() => this.GetSharedBufferList(int.MaxValue, int.MaxValue);
///
///Returns an array of direct NIO buffers if the currently pending messages are made of {@link ByteBuf} only.
///{@link #nioBufferCount()} and {@link #nioBufferSize()} will return the number of NIO buffers in the returned
///array and the total number of readable bytes of the NIO buffers respectively.
///<p>
///Note that the returned array is reused and thus should not escape
///{@link AbstractChannel#doWrite(ChannelOutboundBuffer)}.
///Refer to {@link NioSocketChannel#doWrite(ChannelOutboundBuffer)} for an example.
///</p>
/// @param maxCount The maximum amount of buffers that will be added to the return value.
/// @param maxBytes A hint toward the maximum number of bytes to include as part of the return value. Note that this
/// value maybe exceeded because we make a best effort to include at least 1 {@link ByteBuffer}
/// in the return value to ensure write progress is made.
///
/// <summary>
/// Returns a list of direct ArraySegment&lt;byte&gt;, if the currently pending messages are made of
/// <see cref="IByteBuffer"/> instances only. <see cref="NioBufferSize"/> will return the total number of
/// readable bytes of these buffers.
/// <para>
/// Note that the returned array is reused and thus should not escape
/// <see cref="AbstractChannel.DoWrite(ChannelOutboundBuffer)"/>. Refer to
/// <see cref="TcpSocketChannel.DoWrite(ChannelOutboundBuffer)"/> for an example.
/// </para>
/// </summary>
/// <param name="maxCount">The maximum amount of buffers that will be added to the return value.</param>
/// <param name="maxBytes">A hint toward the maximum number of bytes to include as part of the return value. Note that this value maybe exceeded because we make a best effort to include at least 1 <see cref="IByteBuffer"/> in the return value to ensure write progress is made.</param>
/// <returns>A list of ArraySegment&lt;byte&gt; buffers.</returns>
public List<ArraySegment<byte>> GetSharedBufferList(int maxCount, long maxBytes)
{
Debug.Assert(maxCount > 0);
@ -426,40 +439,35 @@ namespace DotNetty.Transport.Channels
return nioBuffers;
}
/**
* Returns the number of bytes that can be written out of the {@link ByteBuffer} array that was
* obtained via {@link #nioBuffers()}. This method <strong>MUST</strong> be called after {@link #nioBuffers()}
* was called.
*/
/// <summary>
/// Returns the number of bytes that can be written out of the <see cref="IByteBuffer"/> array that was
/// obtained via <see cref="GetSharedBufferList()"/>. This method <strong>MUST</strong> be called after
/// <see cref="GetSharedBufferList()"/>.
/// </summary>
public long NioBufferSize => this.nioBufferSize;
/// <summary>
/// Returns an array of direct NIO buffers if the currently pending messages are made of {@link ByteBuf} only.
/// {@link #IoBufferCount} and {@link #NioBufferSize} will return the number of NIO buffers in the returned
/// array and the total number of readable bytes of the NIO buffers respectively.
/// <p>
/// Note that the returned array is reused and thus should not escape
/// {@link AbstractChannel#doWrite(ChannelOutboundBuffer)}.
/// Refer to {@link NioSocketChannel#doWrite(ChannelOutboundBuffer)} for an example.
/// </p>
/// </summary>
/// <summary>
/// Returns {@code true} if and only if {@linkplain #totalPendingWriteBytes() the total number of pending bytes} did
/// not exceed the write watermark of the {@link Channel} and
/// no {@linkplain #SetUserDefinedWritability(int, bool) user-defined writability flag} has been set to
/// {@code false}.
/// Returns <c>true</c> if and only if the total number of pending bytes (<see cref="TotalPendingWriteBytes"/>)
/// did not exceed the write watermark of the <see cref="IChannel"/> and no user-defined writability flag
/// (<see cref="SetUserDefinedWritability(int, bool)"/>) has been set to <c>false</c>.
/// </summary>
public bool IsWritable => this.unwritable == 0;
/// <summary>
/// Returns {@code true} if and only if the user-defined writability flag at the specified index is set to
/// {@code true}.
/// Returns <c>true</c> if and only if the user-defined writability flag at the specified index is set to
/// <c>true</c>.
/// </summary>
/// <param name="index">The index to check for user-defined writability.</param>
/// <returns>
/// <c>true</c> if the user-defined writability flag at the specified index is set to <c>true</c>.
/// </returns>
public bool GetUserDefinedWritability(int index) => (this.unwritable & WritabilityMask(index)) == 0;
/// <summary>
/// Sets a user-defined writability flag at the specified index.
/// Sets a user-defined writability flag at the specified index.
/// </summary>
/// <param name="index">The index where a writability flag should be set.</param>
/// <param name="writable">Whether to set the index as writable or not.</param>
public void SetUserDefinedWritability(int index, bool writable)
{
if (writable)
@ -565,13 +573,13 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Returns the number of flushed messages in this {@link ChannelOutboundBuffer}.
/// Returns the number of flushed messages in this <see cref="ChannelOutboundBuffer"/>.
/// </summary>
public int Size => this.flushed;
/// <summary>
/// Returns {@code true} if there are flushed messages in this {@link ChannelOutboundBuffer} or {@code false}
/// otherwise.
/// Returns <c>true</c> if there are flushed messages in this <see cref="ChannelOutboundBuffer"/>, otherwise
/// <c>false</c>.
/// </summary>
public bool IsEmpty => this.flushed == 0;
@ -685,10 +693,14 @@ namespace DotNetty.Transport.Channels
public long TotalPendingWriteBytes() => Volatile.Read(ref this.totalPendingSize);
/**
* Get how many bytes can be written until {@link #isWritable()} returns {@code false}.
* This quantity will always be non-negative. If {@link #isWritable()} is {@code false} then 0.
*/
/// <summary>
/// Gets the number of bytes that can be written before <see cref="IsWritable"/> returns <c>false</c>.
/// This quantity will always be non-negative. If <see cref="IsWritable"/> is already <c>false</c>, then 0 is
/// returned.
/// </summary>
/// <returns>
/// The number of bytes that can be written before <see cref="IsWritable"/> returns <c>false</c>.
/// </returns>
public long BytesBeforeUnwritable()
{
long bytes = this.channel.Configuration.WriteBufferHighWaterMark - this.totalPendingSize;
@ -702,10 +714,14 @@ namespace DotNetty.Transport.Channels
return 0;
}
/**
* Get how many bytes must be drained from the underlying buffer until {@link #isWritable()} returns {@code true}.
* This quantity will always be non-negative. If {@link #isWritable()} is {@code true} then 0.
*/
/// <summary>
/// Gets the number of bytes that must be drained from the underlying buffer before <see cref="IsWritable"/>
/// returns <c>true</c>. This quantity will always be non-negative. If <see cref="IsWritable"/> is already
/// <c>true</c>, then 0 is returned.
/// </summary>
/// <returns>
/// The number of bytes that can be written before <see cref="IsWritable"/> returns <c>true</c>.
/// </returns>
public long BytesBeforeWritable()
{
long bytes = this.totalPendingSize - this.channel.Configuration.WriteBufferLowWaterMark;
@ -719,6 +735,14 @@ namespace DotNetty.Transport.Channels
return 0;
}
/// <summary>
/// Calls <see cref="IMessageProcessor.ProcessMessage"/> for each flushed message in this
/// <see cref="ChannelOutboundBuffer"/> until <see cref="IMessageProcessor.ProcessMessage"/> returns
/// <c>false</c> or there are no more flushed messages to process.
/// </summary>
/// <param name="processor">
/// The <see cref="IMessageProcessor"/> intance to use to process each flushed message.
/// </param>
public void ForEachFlushedMessage(IMessageProcessor processor)
{
Contract.Requires(processor != null);
@ -743,19 +767,15 @@ namespace DotNetty.Transport.Channels
while (this.IsFlushedEntry(entry));
}
/// <summary>
/// Call {@link IMessageProcessor#processMessage(Object)} for each flushed message
/// in this {@link ChannelOutboundBuffer} until {@link IMessageProcessor#processMessage(Object)}
/// returns {@code false} or there are no more flushed messages to process.
/// </summary>
bool IsFlushedEntry(Entry e) => e != null && e != this.unflushedEntry;
public interface IMessageProcessor
{
/**
* Will be called for each flushed message until it either there are no more flushed messages or this
* method returns {@code false}.
*/
/// <summary>
/// Will be called for each flushed message until it either there are no more flushed messages or this method returns <c>false</c>.
/// </summary>
/// <param name="msg">The message to process.</param>
/// <returns><c>true</c> if the given message was successfully processed, otherwise <c>false</c>.</returns>
bool ProcessMessage(object msg);
}

Просмотреть файл

@ -42,22 +42,17 @@ namespace DotNetty.Transport.Channels
private IMessageSizeEstimatorHandle estimatorHandle;
/// <summary>
/// This is the head of a linked list that is processed by <see cref="CallHandlerAddedForAllHandlers" /> and so process
/// all the pending <see cref="CallHandlerAdded0" />.
/// We only keep the head because it is expected that the list is used infrequently and its size is small.
/// Thus full iterations to do insertions is assumed to be a good compromised to saving memory and tail management
/// complexity.
/// This is the head of a linked list that is processed by <see cref="CallHandlerAddedForAllHandlers" /> and so
/// process all the pending <see cref="CallHandlerAdded0" />. We only keep the head because it is expected that
/// the list is used infrequently and its size is small. Thus full iterations to do insertions is assumed to be
/// a good compromised to saving memory and tail management complexity.
/// </summary>
PendingHandlerCallback pendingHandlerCallbackHead;
/// Set to
/// <c>true</c>
/// once the
/// <see cref="AbstractChannel" />
/// is registered.Once set to
/// <c>true</c>
/// the value will never
/// change.
/// <summary>
/// Set to <c>true</c> once the <see cref="AbstractChannel" /> is registered. Once set to <c>true</c>, the
/// value will never change.
/// </summary>
bool registered;
public DefaultChannelPipeline(IChannel channel)
@ -576,21 +571,6 @@ namespace DotNetty.Transport.Channels
}
}
/// <summary>
/// Waits for a future to finish. If the task is interrupted, then the current thread will be interrupted.
/// It is expected that the task performs any appropriate locking.
/// <p>
/// If the internal call throws a {@link Throwable}, but it is not an instance of {@link LogError} or
/// {@link RuntimeException}, then it is wrapped inside a {@link ChannelPipelineException} and that is
/// thrown instead.
/// </p>
/// @param future wait for this future
/// @see Future#get()
/// @throws LogError if the task threw this.
/// @throws RuntimeException if the task threw this.
/// @throws ChannelPipelineException with a {@link Throwable} as a cause, if the task threw another type of
/// {@link Throwable}.
/// </summary>
public IChannelHandler First() => this.FirstContext()?.Handler;
public IChannelHandlerContext FirstContext()
@ -657,7 +637,7 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Returns the {@link String} representation of this pipeline.
/// Returns the string representation of this pipeline.
/// </summary>
public sealed override string ToString()
{
@ -703,12 +683,11 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Removes all handlers from the pipeline one by one from tail (exclusive) to head (exclusive) to trigger
/// handlerRemoved().
/// Note that we traverse up the pipeline <see cref="DestroyUp" />
/// before traversing down <see cref="DestroyDown" /> so that
/// the handlers are removed after all events are handled.
/// See: https://github.com/netty/netty/issues/3156
/// Removes all handlers from the pipeline one by one from tail (exclusive) to head (exclusive) to trigger
/// <see cref="IChannelHandler.HandlerRemoved"/>. Note that we traverse up the pipeline <see cref="DestroyUp"/>
/// before traversing down <see cref="DestroyDown"/> so that the handlers are removed after all events are
/// handled.
/// See: https://github.com/netty/netty/issues/3156
/// </summary>
void Destroy()
{
@ -968,8 +947,8 @@ namespace DotNetty.Transport.Channels
IEventExecutor ExecutorSafe(IEventExecutor eventExecutor) => eventExecutor ?? (this.channel.Registered || this.registered ? this.channel.EventLoop : null);
/// <summary>
/// Called once a <see cref="Exception" /> hit the end of the <see cref="IChannelPipeline" /> without been handled by
/// the user in <see cref="IChannelHandler.ExceptionCaught(IChannelHandlerContext, Exception)" />.
/// Called once an <see cref="Exception" /> hits the end of the <see cref="IChannelPipeline" /> without being
/// handled by the user in <see cref="IChannelHandler.ExceptionCaught(IChannelHandlerContext, Exception)" />.
/// </summary>
protected virtual void OnUnhandledInboundException(Exception cause)
{
@ -986,9 +965,9 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Called once a message hit the end of the <see cref="IChannelPipeline" /> without been handled by the user
/// in <see cref="IChannelHandler.ChannelRead(IChannelHandlerContext, object)" />. This method is responsible
/// to call <see cref="ReferenceCountUtil.Release(object)" /> on the given msg at some point.
/// Called once a message hits the end of the <see cref="IChannelPipeline" /> without being handled by the user
/// in <see cref="IChannelHandler.ChannelRead(IChannelHandlerContext, object)" />. This method is responsible
/// for calling <see cref="ReferenceCountUtil.Release(object)" /> on the given msg at some point.
/// </summary>
protected virtual void OnUnhandledInboundMessage(object msg)
{

Просмотреть файл

@ -36,16 +36,16 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Return the default implementation which returns {@code -1} for unknown messages.
/// Returns the default implementation, which returns <c>0</c> for unknown messages.
/// </summary>
public static readonly IMessageSizeEstimator Default = new DefaultMessageSizeEstimator(0);
readonly IMessageSizeEstimatorHandle handle;
/// <summary>
/// Create a new instance
/// @param unknownSize The size which is returned for unknown messages.
/// Creates a new instance.
/// </summary>
/// <param name="unknownSize">The size which is returned for unknown messages.</param>
public DefaultMessageSizeEstimator(int unknownSize)
{
Contract.Requires(unknownSize >= 0);

Просмотреть файл

@ -343,20 +343,18 @@ namespace DotNetty.Transport.Channels.Embedded
/// <returns>bufferReadable returns <c>true</c></returns>
public bool Finish() => this.Finish(false);
/**
* Mark this {@link Channel} as finished and release all pending message in the inbound and outbound buffer.
* Any futher try to write data to it will fail.
*
* @return bufferReadable returns {@code true} if any of the used buffers has something left to read
*/
/// <summary>
/// Marks this <see cref="IChannel"/> as finished and releases all pending message in the inbound and outbound
/// buffer. Any futher try to write data to it will fail.
/// </summary>
/// <returns><c>true</c> if any of the used buffers has something left to read, otherwise <c>false</c>.</returns>
public bool FinishAndReleaseAll() => this.Finish(true);
/**
* Mark this {@link Channel} as finished. Any futher try to write data to it will fail.
*
* @param releaseAll if {@code true} all pending message in the inbound and outbound buffer are released.
* @return bufferReadable returns {@code true} if any of the used buffers has something left to read
*/
/// <summary>
/// Marks this <see cref="IChannel"/> as finished. Any futher attempt to write data to it will fail.
/// </summary>
/// <param name="releaseAll">If <c>true</c>, all pending messages in the inbound and outbound buffer are released.</param>
/// <returns><c>true</c> if any of the used buffers has something left to read, otherwise <c>false</c>.</returns>
bool Finish(bool releaseAll)
{
this.CloseSafe();
@ -375,16 +373,16 @@ namespace DotNetty.Transport.Channels.Embedded
}
}
/**
* Release all buffered inbound messages and return {@code true} if any were in the inbound buffer, {@code false}
* otherwise.
*/
/// <summary>
/// Releases all buffered inbound messages.
/// </summary>
/// <returns><c>true</c> if any were in the inbound buffer, otherwise <c>false</c>.</returns>
public bool ReleaseInbound() => ReleaseAll(this.inboundMessages);
/**
* Release all buffered outbound messages and return {@code true} if any were in the outbound buffer, {@code false}
* otherwise.
*/
/// <summary>
/// Releases all buffered outbound messages.
/// </summary>
/// <returns><c>true</c> if any were in the outbound buffer, otherwise <c>false</c>.</returns>
public bool ReleaseOutbound() => ReleaseAll(this.outboundMessages);
static bool ReleaseAll(Queue<object> queue)

Просмотреть файл

@ -10,12 +10,14 @@ namespace DotNetty.Transport.Channels
public interface IChannelHandler
{
/// <summary>
/// The {@link Channel} of the {@link ChannelHandlerContext} was registered with its {@link EventLoop}
/// The <see cref="IChannel"/> of the <see cref="IChannelHandlerContext"/> was registered with its
/// <see cref="IEventLoop"/>.
/// </summary>
void ChannelRegistered(IChannelHandlerContext context);
/// <summary>
/// The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop}
/// The <see cref="IChannel"/> of the <see cref="IChannelHandlerContext"/> was unregistered from its
/// <see cref="IEventLoop"/>.
/// </summary>
void ChannelUnregistered(IChannelHandlerContext context);
@ -28,8 +30,8 @@ namespace DotNetty.Transport.Channels
void ChannelReadComplete(IChannelHandlerContext context);
/// <summary>
/// Gets called once the writable state of a {@link Channel} changed. You can check the state with
/// {@link Channel#isWritable()}.
/// Gets called once the writable state of a <see cref="IChannel"/> changed. You can check the state with
/// <see cref="IChannel.IsWritable"/>.
/// </summary>
void ChannelWritabilityChanged(IChannelHandlerContext context);
@ -42,30 +44,33 @@ namespace DotNetty.Transport.Channels
void Flush(IChannelHandlerContext context);
/// <summary>
/// Called once a bind operation is made.
/// @param context the {@link ChannelHandlerContext} for which the bind operation is made
/// @param localAddress the {@link java.net.SocketAddress} to which it should bound
/// @param promise the {@link ChannelPromise} to notify once the operation completes
/// @throws Exception thrown if an error accour
/// Called once a bind operation is made.
/// </summary>
/// <param name="context">
/// The <see cref="IChannelHandlerContext"/> for which the bind operation is made.
/// </param>
/// <param name="localAddress">The <see cref="EndPoint"/> to which it should bind.</param>
/// <returns>An await-able task.</returns>
Task BindAsync(IChannelHandlerContext context, EndPoint localAddress);
/// <summary>
/// Called once a connect operation is made.
/// @param context the {@link ChannelHandlerContext} for which the connect operation is made
/// @param remoteAddress the {@link SocketAddress} to which it should connect
/// @param localAddress the {@link SocketAddress} which is used as source on connect
/// @param promise the {@link ChannelPromise} to notify once the operation completes
/// @throws Exception thrown if an error accour
/// Called once a connect operation is made.
/// </summary>
/// <param name="context">
/// The <see cref="IChannelHandlerContext"/> for which the connect operation is made.
/// </param>
/// <param name="remoteAddress">The <see cref="EndPoint"/> to which it should connect.</param>
/// <param name="localAddress">The <see cref="EndPoint"/> which is used as source on connect.</param>
/// <returns>An await-able task.</returns>
Task ConnectAsync(IChannelHandlerContext context, EndPoint remoteAddress, EndPoint localAddress);
/// <summary>
/// Called once a disconnect operation is made.
/// @param context the {@link ChannelHandlerContext} for which the disconnect operation is made
/// @param promise the {@link ChannelPromise} to notify once the operation completes
/// @throws Exception thrown if an error accour
/// Called once a disconnect operation is made.
/// </summary>
/// <param name="context">
/// The <see cref="IChannelHandlerContext"/> for which the disconnect operation is made.
/// </param>
/// <returns>An await-able task.</returns>
Task DisconnectAsync(IChannelHandlerContext context);
Task CloseAsync(IChannelHandlerContext context);

Просмотреть файл

@ -17,17 +17,17 @@ namespace DotNetty.Transport.Channels
IByteBufferAllocator Allocator { get; }
/// <summary>
/// Returns the {@link EventExecutor} which is used to execute an arbitrary task.
/// Returns the <see cref="IEventExecutor"/> which is used to execute an arbitrary task.
/// </summary>
IEventExecutor Executor { get; }
/// <summary>
/// The unique name of the {@link IChannelHandlerContext}.
/// The unique name of the <see cref="IChannelHandlerContext"/>.
/// </summary>
/// <remarks>
/// The name was used when the {@link IChannelHandler}
/// was added to the {@link IChannelPipeline}. This name can also be used to access the registered
/// {@link IChannelHandler} from the {@link IChannelPipeline}.
/// The name was used when the <see cref="IChannelHandler"/> was added to the <see cref="IChannelPipeline"/>.
/// This name can also be used to access the registered <see cref="IChannelHandler"/> from the
/// <see cref="IChannelPipeline"/>.
/// </remarks>
string Name { get; }
@ -36,19 +36,19 @@ namespace DotNetty.Transport.Channels
bool Removed { get; }
/// <summary>
/// A {@link Channel} was registered to its {@link EventLoop}.
/// This will result in having the {@link ChannelHandler#channelRegistered(ChannelHandlerContext)} method
/// called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// A <see cref="IChannel"/> was registered to its <see cref="IEventLoop"/>. This will result in having the
/// <see cref="IChannelHandler.ChannelRegistered"/> method called of the next <see cref="IChannelHandler"/>
/// contained in the <see cref="IChannelPipeline"/> of the <see cref="IChannel"/>.
/// </summary>
/// <returns>The current <see cref="IChannelHandlerContext"/>.</returns>
IChannelHandlerContext FireChannelRegistered();
/// <summary>
/// A {@link Channel} was unregistered from its {@link EventLoop}.
/// This will result in having the {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)} method
/// called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// A <see cref="IChannel"/> was unregistered from its <see cref="IEventLoop"/>. This will result in having the
/// <see cref="IChannelHandler.ChannelUnregistered"/> method called of the next <see cref="IChannelHandler"/>
/// contained in the <see cref="IChannelPipeline"/> of the <see cref="IChannel"/>.
/// </summary>
/// <returns>The current <see cref="IChannelHandlerContext"/>.</returns>
IChannelHandlerContext FireChannelUnregistered();
IChannelHandlerContext FireChannelActive();
@ -74,67 +74,64 @@ namespace DotNetty.Transport.Channels
Task WriteAndFlushAsync(object message);
/// <summary>
/// Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
/// completes, either because the operation was successful or because of an error.
/// <p />
/// This will result in having the
/// {@link ChannelHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
/// called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// Request to bind to the given <see cref="EndPoint"/>.
/// <para>
/// This will result in having the <see cref="IChannelHandler.BindAsync"/> method called of the next
/// <see cref="IChannelHandler"/> contained in the <see cref="IChannelPipeline"/> of the
/// <see cref="IChannel"/>.
/// </para>
/// </summary>
/// <param name="localAddress">The <see cref="EndPoint"/> to bind to.</param>
/// <returns>An await-able task.</returns>
Task BindAsync(EndPoint localAddress);
/// <summary>
/// Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
/// completes, either because the operation was successful or because of an error.
/// <p />
/// If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
/// a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
/// will be used.
/// <p />
/// This will result in having the
/// {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
/// method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// Request to connect to the given <see cref="EndPoint"/>.
/// <para>
/// This will result in having the <see cref="IChannelHandler.ConnectAsync"/> method called of the next
/// <see cref="IChannelHandler"/> contained in the <see cref="IChannelPipeline"/> of the
/// <see cref="IChannel"/>.
/// </para>
/// </summary>
/// <param name="remoteAddress">The <see cref="EndPoint"/> to connect to.</param>
/// <returns>An await-able task.</returns>
Task ConnectAsync(EndPoint remoteAddress);
/// <summary>
/// Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
/// {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
/// an error.
/// <p />
/// This will result in having the
/// {@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
/// method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// Request to connect to the given <see cref="EndPoint"/> while also binding to the localAddress.
/// <para>
/// This will result in having the <see cref="IChannelHandler.ConnectAsync"/> method called of the next
/// <see cref="IChannelHandler"/> contained in the <see cref="IChannelPipeline"/> of the
/// <see cref="IChannel"/>.
/// </para>
/// </summary>
/// <param name="remoteAddress">The <see cref="EndPoint"/> to connect to.</param>
/// <param name="localAddress">The <see cref="EndPoint"/> to bind to.</param>
/// <returns>An await-able task.</returns>
Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress);
/// <summary>
/// Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
/// either because the operation was successful or because of an error.
/// <p />
/// This will result in having the
/// {@link ChannelHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
/// method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// Request to disconnect from the remote peer.
/// <para>
/// This will result in having the <see cref="IChannelHandler.DisconnectAsync"/> method called of the next
/// <see cref="IChannelHandler"/> contained in the <see cref="IChannelPipeline"/> of the
/// <see cref="IChannel"/>.
/// </para>
/// </summary>
/// <returns>An await-able task.</returns>
Task DisconnectAsync();
Task CloseAsync();
/// <summary>
/// Request to deregister from the previous assigned {@link EventExecutor} and notify the
/// {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
/// an error.
/// The given {@link ChannelPromise} will be notified.
/// <p />
/// This will result in having the
/// {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
/// method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
/// {@link Channel}.
/// Request to deregister from the previous assigned <see cref="IEventExecutor"/>.
/// <para>
/// This will result in having the <see cref="IChannelHandler.DeregisterAsync"/> method called of the next
/// <see cref="IChannelHandler"/> contained in the <see cref="IChannelPipeline"/> of the
/// <see cref="IChannel"/>.
/// </para>
/// </summary>
/// <returns>An await-able task.</returns>
Task DeregisterAsync();
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -6,10 +6,10 @@ namespace DotNetty.Transport.Channels
public interface IMessageSizeEstimatorHandle
{
/// <summary>
/// Calculate the size of the given message.
/// @param msg The message for which the size should be calculated
/// @return size The size in bytes. The returned size must be >= 0
/// Calculates the size of the given message.
/// </summary>
/// <param name="msg">The message for which the size should be calculated.</param>
/// <returns>The size in bytes. The returned size must be >= 0</returns>
int Size(object msg);
}
}

Просмотреть файл

@ -3,10 +3,11 @@
namespace DotNetty.Transport.Channels
{
using DotNetty.Transport.Channels.Sockets;
/// <summary>
/// A {@link Channel} that accepts an incoming connection attempt and creates
/// its child {@link Channel}s by accepting them. {@link ServerSocketChannel} is
/// a good example.
/// A <see cref="IChannel"/> that accepts an incoming connection attempt and creates its child
/// <see cref="IChannel"/>s by accepting them. <see cref="IServerSocketChannel"/> is a good example.
/// </summary>
public interface IServerChannel : IChannel
{

Просмотреть файл

@ -14,9 +14,9 @@ namespace DotNetty.Transport.Channels.Local
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
/**
* A {@link Channel} for the local transport.
*/
/// <summary>
/// A <see cref="IChannel"/> for the local transport.
/// </summary>
public class LocalChannel : AbstractChannel
{
enum State

Просмотреть файл

@ -8,9 +8,9 @@ namespace DotNetty.Transport.Channels.Local
using DotNetty.Common.Concurrency;
using DotNetty.Common.Internal;
/**
* A {@link ServerChannel} for the local transport which allows in VM communication.
*/
/// <summary>
/// A <see cref="IServerChannel"/> for the local transport which allows in VM communication.
/// </summary>
public class LocalServerChannel : AbstractServerChannel
{
readonly IQueue<object> inboundBuffer = PlatformDependent.NewMpscQueue<object>();
@ -111,10 +111,11 @@ namespace DotNetty.Transport.Channels.Local
return child;
}
/**
* A factory method for {@link LocalChannel}s. Users may override it
* to create custom instances of {@link LocalChannel}s.
*/
/// <summary>
/// A factory method for <see cref="LocalChannel"/>s. Users may override it to create custom instances of <see cref="LocalChannel"/>s.
/// </summary>
/// <param name="peer">An existing <see cref="LocalChannel"/> that will act as a peer for the new channel.</param>
/// <returns>The newly created <see cref="LocalChannel"/> instance.</returns>
protected LocalChannel NewLocalChannel(LocalChannel peer) => new LocalChannel(this, peer);
void Serve0(LocalChannel child)

Просмотреть файл

@ -12,12 +12,11 @@ namespace DotNetty.Transport.Channels
using DotNetty.Common.Internal.Logging;
using DotNetty.Common.Utilities;
/**
* A queue of write operations which are pending for later execution. It also updates the
* {@linkplain Channel#isWritable() writability} of the associated {@link Channel}, so that
* the pending write operations are also considered to determine the writability.
*/
/// <summary>
/// A queue of write operations which are pending for later execution. It also updates the writability of the
/// associated <see cref="IChannel"/> (<see cref="IChannel.IsWritable"/>), so that the pending write operations are
/// also considered to determine the writability.
/// </summary>
public sealed class PendingWriteQueue
{
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<PendingWriteQueue>();
@ -40,10 +39,9 @@ namespace DotNetty.Transport.Channels
this.estimatorHandle = ctx.Channel.Configuration.MessageSizeEstimator.NewHandle();
}
/**
* Returns {@code true} if there are no pending write operations left in this queue.
*/
/// <summary>
/// Returns <c>true</c> if there are no pending write operations left in this queue.
/// </summary>
public bool IsEmpty
{
get
@ -54,10 +52,9 @@ namespace DotNetty.Transport.Channels
}
}
/**
* Returns the number of pending write operations.
*/
/// <summary>
/// Returns the number of pending write operations.
/// </summary>
public int Size
{
get
@ -68,10 +65,11 @@ namespace DotNetty.Transport.Channels
}
}
/**
* Add the given {@code msg} and {@link ChannelPromise}.
*/
/// <summary>
/// Adds the given message to this <see cref="PendingWriteQueue"/>.
/// </summary>
/// <param name="msg">The message to add to the <see cref="PendingWriteQueue"/>.</param>
/// <returns>An await-able task.</returns>
public Task Add(object msg)
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -103,11 +101,11 @@ namespace DotNetty.Transport.Channels
return promise.Task;
}
/**
* Remove all pending write operation and fail them with the given {@link Throwable}. The message will be released
* via {@link ReferenceCountUtil#safeRelease(Object)}.
*/
/// <summary>
/// Removes all pending write operations, and fail them with the given <see cref="Exception"/>. The messages
/// will be released via <see cref="ReferenceCountUtil.SafeRelease(object)"/>.
/// </summary>
/// <param name="cause">The <see cref="Exception"/> to fail with.</param>
public void RemoveAndFailAll(Exception cause)
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -130,11 +128,11 @@ namespace DotNetty.Transport.Channels
this.AssertEmpty();
}
/**
* Remove a pending write operation and fail it with the given {@link Throwable}. The message will be released via
* {@link ReferenceCountUtil#safeRelease(Object)}.
*/
/// <summary>
/// Remove a pending write operation and fail it with the given <see cref="Exception"/>. The message will be
/// released via <see cref="ReferenceCountUtil.SafeRelease(object)"/>.
/// </summary>
/// <param name="cause">The <see cref="Exception"/> to fail with.</param>
public void RemoveAndFail(Exception cause)
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -152,14 +150,10 @@ namespace DotNetty.Transport.Channels
this.Recycle(write, true);
}
/**
* Remove all pending write operation and performs them via
* {@link ChannelHandlerContext#write(Object, ChannelPromise)}.
*
* @return {@link ChannelFuture} if something was written and {@code null}
* if the {@link PendingWriteQueue} is empty.
*/
/// <summary>
/// Removes all pending write operation and performs them via <see cref="IChannelHandlerContext.WriteAsync"/>
/// </summary>
/// <returns>An await-able task.</returns>
public Task RemoveAndWriteAllAsync()
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -198,14 +192,10 @@ namespace DotNetty.Transport.Channels
void AssertEmpty() => Contract.Assert(this.tail == null && this.head == null && this.size == 0);
/**
* Removes a pending write operation and performs it via
* {@link ChannelHandlerContext#write(Object, ChannelPromise)}.
*
* @return {@link ChannelFuture} if something was written and {@code null}
* if the {@link PendingWriteQueue} is empty.
*/
/// <summary>
/// Removes a pending write operation and performs it via <see cref="IChannelHandlerContext.WriteAsync"/>.
/// </summary>
/// <returns>An await-able task.</returns>
public Task RemoveAndWriteAsync()
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -223,9 +213,12 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Removes a pending write operation and release it's message via {@link ReferenceCountUtil#safeRelease(Object)}.
/// Removes a pending write operation and releases it's message via
/// <see cref="ReferenceCountUtil.SafeRelease(object)"/>.
/// </summary>
/// <returns><seealso cref="TaskCompletionSource" /> of the pending write or <c>null</c> if the queue is empty.</returns>
/// <returns>
/// The <see cref="TaskCompletionSource" /> of the pending write, or <c>null</c> if the queue is empty.
/// </returns>
public TaskCompletionSource Remove()
{
Contract.Assert(this.ctx.Executor.InEventLoop);
@ -242,7 +235,7 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Return the current message or {@code null} if empty.
/// Return the current message, or <c>null</c> if the queue is empty.
/// </summary>
public object Current
{
@ -283,10 +276,9 @@ namespace DotNetty.Transport.Channels
this.buffer?.DecrementPendingOutboundBytes(writeSize);
}
/**
* Holds all meta-data and construct the linked-list structure.
*/
/// <summary>
/// Holds all meta-data and constructs the linked-list structure.
/// </summary>
sealed class PendingWrite
{
static readonly ThreadLocalPool<PendingWrite> Pool = new ThreadLocalPool<PendingWrite>(handle => new PendingWrite(handle));

Просмотреть файл

@ -32,12 +32,11 @@ namespace DotNetty.Transport.Channels.Pool
return pool;
}
/**
* Remove the {@link ChannelPool} from this {@link AbstractChannelPoolMap}. Returns {@code true} if removed,
* {@code false} otherwise.
*
* Please note that {@code null} keys are not allowed.
*/
/// <summary>
/// Removes the <see cref="IChannelPool"/> from this <see cref="AbstractChannelPoolMap{TKey, TPool}"/>.
/// </summary>
/// <param name="key">The key to remove. Must not be null.</param>
/// <returns><c>true</c> if removed, otherwise <c>false</c>.</returns>
public bool Remove(TKey key)
{
Contract.Requires(key != null);
@ -53,14 +52,14 @@ namespace DotNetty.Transport.Channels.Pool
return new ReadOnlyIterator<Entry<K, P>>(this.map.entrySet().iterator());
}*/
/**
* Returns the number of {@link ChannelPool}s currently in this {@link AbstractChannelPoolMap}.
*/
/// <summary>
/// Returns the number of <see cref="IChannelPool"/>s currently in this <see cref="AbstractChannelPoolMap{TKey, TPool}"/>.
/// </summary>
public int Count => this.map.Count;
/**
* Returns {@code true} if the {@link AbstractChannelPoolMap} is empty, otherwise {@code false}.
*/
/// <summary>
/// Returns <c>true</c> if the <see cref="AbstractChannelPoolMap{TKey, TPool}"/> is empty, otherwise <c>false</c>.
/// </summary>
public bool IsEmpty => this.map.Count == 0;
public bool Contains(TKey key)
@ -69,9 +68,11 @@ namespace DotNetty.Transport.Channels.Pool
return this.map.ContainsKey(key);
}
/**
* Called once a new {@link ChannelPool} needs to be created as non exists yet for the {@code key}.
*/
/// <summary>
/// Called once a new <see cref="IChannelPool"/> needs to be created as none exists yet for the <paramref name="key"/>.
/// </summary>
/// <param name="key">The <typeparamref name="TKey"/> to create a new <typeparamref name="TPool"/> for.</param>
/// <returns>The new <typeparamref name="TPool"/> corresponding to the given <typeparamref name="TKey"/>.</returns>
protected abstract TPool NewPool(TKey key);
public void Dispose()

Просмотреть файл

@ -6,9 +6,9 @@ namespace DotNetty.Transport.Channels.Pool
using System.Threading.Tasks;
using DotNetty.Common.Utilities;
/**
* {@link ChannelHealthChecker} implementation that checks if {@link Channel#isActive()} returns {@code true}.
*/
/// <summary>
/// <see cref="IChannelHealthChecker"/> implementation that checks if <see cref="IChannel.Active"/> returns <c>true</c>.
/// </summary>
public class ChannelActiveHealthChecker : IChannelHealthChecker
{
public static readonly IChannelHealthChecker Instance;

Просмотреть файл

@ -15,10 +15,10 @@ namespace DotNetty.Transport.Channels.Pool
using DotNetty.Common.Internal;
using DotNetty.Transport.Bootstrapping;
/**
* {@link ChannelPool} implementation that takes another {@link ChannelPool} implementation and enforce a maximum
* number of concurrent connections.
*/
/// <summary>
/// An <see cref="IChannelPool"/> implementation that takes another <see cref="IChannelPool"/> implementation and
/// enforces a maximum number of concurrent connections.
/// </summary>
public class FixedChannelPool : SimpleChannelPool
{
static readonly InvalidOperationException FullException = new InvalidOperationException("Too many outstanding acquire operations");
@ -33,14 +33,14 @@ namespace DotNetty.Transport.Channels.Pool
{
None,
/**
* Create a new connection when the timeout is detected.
*/
/// <summary>
/// Creates a new connection when the timeout is detected.
/// </summary>
New,
/**
* Fail the {@link Future} of the acquire call with a {@link TimeoutException}.
*/
/// <summary>
/// Fails the <see cref="TaskCompletionSource"/> of the acquire call with a <see cref="System.TimeoutException"/>.
/// </summary>
Fail
}
@ -58,97 +58,118 @@ namespace DotNetty.Transport.Channels.Pool
int pendingAcquireCount;
bool closed;
/**
* Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions
* @param maxConnections the number of maximal active connections, once this is reached new tries to acquire
* a {@link Channel} will be delayed until a connection is returned to the pool again.
*/
/**
* Creates a new instance using the {@link ChannelHealthChecker#ACTIVE}.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions
* @param maxConnections the number of maximal active connections, once this is reached new tries to
* acquire a {@link Channel} will be delayed until a connection is returned to the
* pool again.
* @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will
* be failed.
*/
/// <summary>
/// Creates a new <see cref="FixedChannelPool"/> instance using the <see cref="ChannelActiveHealthChecker"/>.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="maxConnections">
/// The number of maximal active connections. Once this is reached, new attempts to acquire an
/// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
/// </param>
/// <param name="maxPendingAcquires">
/// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
/// </param>
public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, int maxConnections, int maxPendingAcquires = int.MaxValue)
: this(bootstrap, handler, ChannelActiveHealthChecker.Instance, AcquireTimeoutAction.None, Timeout.InfiniteTimeSpan, maxConnections, maxPendingAcquires)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
* @param action the {@link AcquireTimeoutAction} to use or {@code null} if non should be used.
* In this case {@param acquireTimeoutMillis} must be {@code -1}.
* @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or
* the {@link AcquireTimeoutAction} takes place.
* @param maxConnections the number of maximal active connections, once this is reached new tries to
* acquire a {@link Channel} will be delayed until a connection is returned to the
* pool again.
* @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will
* be failed.
*/
/// <summary>
/// Creates a new <see cref="FixedChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
/// <param name="action">
/// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
/// <paramref name="acquireTimeout"/> must also be <c>null</c>.
/// </param>
/// <param name="acquireTimeout">
/// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
/// <see cref="AcquireTimeoutAction"/> takes place.
/// </param>
/// <param name="maxConnections">
/// The number of maximal active connections. Once this is reached, new attempts to acquire an
/// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
/// </param>
/// <param name="maxPendingAcquires">
/// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
/// </param>
public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires)
: this(bootstrap, handler, healthChecker, action, acquireTimeout, maxConnections, maxPendingAcquires, true)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
* @param action the {@link AcquireTimeoutAction} to use or {@code null} if non should be used.
* In this case {@param acquireTimeoutMillis} must be {@code -1}.
* @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or
* the {@link AcquireTimeoutAction} takes place.
* @param maxConnections the number of maximal active connections, once this is reached new tries to
* acquire a {@link Channel} will be delayed until a connection is returned to the
* pool again.
* @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will
* be failed.
* @param releaseHealthCheck will check channel health before offering back if this parameter set to
* {@code true}.
*/
/// <summary>
/// Creates a new <see cref="FixedChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
/// <param name="action">
/// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
/// <paramref name="acquireTimeout"/> must also be <c>null</c>.
/// </param>
/// <param name="acquireTimeout">
/// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
/// <see cref="AcquireTimeoutAction"/> takes place.
/// </param>
/// <param name="maxConnections">
/// The number of maximal active connections. Once this is reached, new attempts to acquire an
/// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
/// </param>
/// <param name="maxPendingAcquires">
/// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
/// </param>
/// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param>
public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck)
: this(bootstrap, handler, healthChecker, action, acquireTimeout, maxConnections, maxPendingAcquires, releaseHealthCheck, true)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link ChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link ChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
* @param action the {@link AcquireTimeoutAction} to use or {@code null} if non should be used.
* In this case {@param acquireTimeoutMillis} must be {@code -1}.
* @param acquireTimeoutMillis the time (in milliseconds) after which an pending acquire must complete or
* the {@link AcquireTimeoutAction} takes place.
* @param maxConnections the number of maximal active connections, once this is reached new tries to
* acquire a {@link Channel} will be delayed until a connection is returned to the
* pool again.
* @param maxPendingAcquires the maximum number of pending acquires. Once this is exceed acquire tries will
* be failed.
* @param releaseHealthCheck will check channel health before offering back if this parameter set to
* {@code true}.
* @param lastRecentUsed {@code true} {@link Channel} selection will be LIFO, if {@code false} FIFO.
*/
/// <summary>
/// Creates a new <see cref="FixedChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
/// <param name="action">
/// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
/// <paramref name="acquireTimeout"/> must also be <c>null</c>.
/// </param>
/// <param name="acquireTimeout">
/// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
/// <see cref="AcquireTimeoutAction"/> takes place.
/// </param>
/// <param name="maxConnections">
/// The number of maximal active connections. Once this is reached, new attempts to acquire an
/// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
/// </param>
/// <param name="maxPendingAcquires">
/// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
/// </param>
/// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param>
/// <param name="lastRecentUsed">
/// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
/// </param>
public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck, bool lastRecentUsed)
: base(bootstrap, handler, healthChecker, releaseHealthCheck, lastRecentUsed)
{

Просмотреть файл

@ -5,18 +5,17 @@ namespace DotNetty.Transport.Channels.Pool
{
using System.Threading.Tasks;
/**
* Called before a {@link Channel} will be returned via {@link ChannelPool#acquire()} or
* {@link ChannelPool#acquire(Promise)}.
*/
/// <summary>
/// Called before an <see cref="IChannel"/> will be returned via <see cref="IChannelPool.AcquireAsync"/>.
/// </summary>
public interface IChannelHealthChecker
{
/**
* Check if the given channel is healthy which means it can be used. The returned {@link Future} is notified once
* the check is complete. If notified with {@link Boolean#TRUE} it can be used {@link Boolean#FALSE} otherwise.
*
* This method will be called by the {@link EventLoop} of the {@link Channel}.
*/
/// <summary>
/// Checks if the given channel is healthy (which means it can be used). This method will be called by the
/// <see cref="IEventLoop"/> of the given <see cref="IChannel"/>
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> to check for healthiness.</param>
/// <returns><c>true</c> if the given <see cref="IChannel"/> is healthy, otherwise <c>false</c>.</returns>
ValueTask<bool> IsHealthyAsync(IChannel channel);
}
}

Просмотреть файл

@ -6,27 +6,29 @@ namespace DotNetty.Transport.Channels.Pool
using System;
using System.Threading.Tasks;
/**
* Allows to acquire and release {@link Channel} and so act as a pool of these.
*/
/// <summary>
/// Allows the acquisition and release of <see cref="IChannel"/> instances, and so act as a pool of these.
/// </summary>
public interface IChannelPool : IDisposable
{
/**
* Acquire a {@link Channel} from this {@link ChannelPool}. The returned {@link Future} is notified once
* the acquire is successful and failed otherwise.
*
* <strong>Its important that an acquired is always released to the pool again, even if the {@link Channel}
* is explicitly closed..</strong>
*/
/// <summary>
/// Acquires an <see cref="IChannel"/> from this <see cref="IChannelPool"/>.
/// <para>
/// It is important that an acquired <see cref="IChannel"/> is always released to the pool again via the
/// <see cref="ReleaseAsync"/> method, even if the <see cref="IChannel"/> is explicitly closed.
/// </para>
/// </summary>
/// <returns>The aquired <see cref="IChannel"/>.</returns>
ValueTask<IChannel> AcquireAsync();
/**
* Acquire a {@link Channel} from this {@link ChannelPool}. The given {@link Promise} is notified once
* the acquire is successful and failed otherwise.
*
* <strong>Its important that an acquired is always released to the pool again, even if the {@link Channel}
* is explicitly closed..</strong>
*/
/// <summary>
/// Releases a previously aquired <see cref="IChannel"/> from this <see cref="IChannelPool"/>, allowing it to
/// be aquired again by another caller.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> instance to be released.</param>
/// <returns>
/// <c>true</c> if the <see cref="IChannel"/> was successfully released, otherwise <c>false</c>.
/// </returns>
ValueTask<bool> ReleaseAsync(IChannel channel);
}
}

Просмотреть файл

@ -3,32 +3,28 @@
namespace DotNetty.Transport.Channels.Pool
{
/**
* Handler which is called for various actions done by the {@link ChannelPool}.
*/
/// <summary>
/// Handler which is called for various actions done by the <see cref="IChannelPool"/>.
/// </summary>
public interface IChannelPoolHandler
{
/**
* Called once a {@link Channel} was released by calling {@link ChannelPool#release(Channel)} or
* {@link ChannelPool#release(Channel, Promise)}.
*
* This method will be called by the {@link EventLoop} of the {@link Channel}.
*/
/// <summary>
/// Called once a <see cref="IChannel"/> was released by calling <see cref="IChannelPool.ReleaseAsync"/>.
/// This method will be called by the <see cref="IEventLoop"/> of the <see cref="IChannel"/>.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> instance which was released.</param>
void ChannelReleased(IChannel channel);
/**
* Called once a {@link Channel} was acquired by calling {@link ChannelPool#acquire()} or
* {@link ChannelPool#acquire(Promise)}.
*
* This method will be called by the {@link EventLoop} of the {@link Channel}.
*/
/// <summary>
/// Called once a <see cref="IChannel"/> was acquired by calling <see cref="IChannelPool.AcquireAsync"/>.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> instance which was aquired.</param>
void ChannelAcquired(IChannel channel);
/**
* Called once a new {@link Channel} is created in the {@link ChannelPool}.
*
* This method will be called by the {@link EventLoop} of the {@link Channel}.
*/
/// <summary>
/// Called once a new <see cref="IChannel"/> is created in the <see cref="IChannelPool"/>.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> instance which was aquired.</param>
void ChannelCreated(IChannel channel);
}
}

Просмотреть файл

@ -3,33 +3,29 @@
namespace DotNetty.Transport.Channels.Pool
{
/**
* Allows to map {@link ChannelPool} implementations to a specific key.
*
* @param <K> the type of the key
* @param <P> the type of the {@link ChannelPool}
*/
/// <summary>
/// Allows the mapping of <see cref="IChannelPool"/> implementations to a specific key.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TPool">The type of the <see cref="IChannelPool"/>.</typeparam>
public interface IChannelPoolMap<TKey, TPool>
where TPool : IChannelPool
{
/**
* Return the {@link ChannelPool} for the {@code code}. This will never return {@code null},
* but create a new {@link ChannelPool} if non exists for they requested {@code key}.
*
* Please note that {@code null} keys are not allowed.
*/
/// <summary>
/// Returns the <see cref="IChannelPool"/> for the <paramref name="key"/>. This will never return <c>null</c>,
/// but create a new <see cref="IChannelPool"/> if non exists for they requested <paramref name="key"/>.
/// Please note that <c>null</c> keys are not allowed.
/// </summary>
/// <param name="key">The key for the desired <see cref="IChannelPool"/></param>
/// <returns>The <see cref="IChannelPool"/> for the specified <paramref name="key"/>.</returns>
TPool Get(TKey key);
/**
* Returns {@code true} if a {@link ChannelPool} exists for the given {@code key}.
*
* Please note that {@code null} keys are not allowed.
*/
/// <summary>
/// Checks whether the <see cref="IChannelPoolMap{TKey,TPool}"/> contains an <see cref="IChannelPool"/> for the
/// given <paramref name="key"/>. Please note that <c>null</c> keys are not allowed.
/// </summary>
/// <param name="key">The key to search the <see cref="IChannelPoolMap{TKey,TPool}"/> for.</param>
/// <returns><c>true</c> if a <see cref="IChannelPool"/> exists for the given <paramref name="key"/>, otherwise <c>false</c>.</returns>
bool Contains(TKey key);
}
/**
* Called before a {@link Channel} will be returned via {@link ChannelPool#acquire()} or
* {@link ChannelPool#acquire(Promise)}.
*/
}

Просмотреть файл

@ -12,13 +12,11 @@ namespace DotNetty.Transport.Channels.Pool
using DotNetty.Common.Utilities;
using DotNetty.Transport.Bootstrapping;
/**
* Simple {@link ChannelPool} implementation which will create new {@link Channel}s if someone tries to acquire
* a {@link Channel} but none is in the pool atm. No limit on the maximal concurrent {@link Channel}s is enforced.
*
* This implementation uses LIFO order for {@link Channel}s in the {@link ChannelPool}.
*
*/
/// <summary>
/// Simple <see cref="IChannelPool"/> implementation which will create new <see cref="IChannel"/>s if someone tries to acquire
/// a <see cref="IChannel"/> but none is in the pool atm. No limit on the maximal concurrent <see cref="IChannel"/>s is enforced.
/// This implementation uses LIFO order for <see cref="IChannel"/>s in the <see cref="IChannelPool"/>.
/// </summary>
public class SimpleChannelPool : IChannelPool
{
public static readonly AttributeKey<SimpleChannelPool> PoolKey = AttributeKey<SimpleChannelPool>.NewInstance("channelPool");
@ -27,56 +25,70 @@ namespace DotNetty.Transport.Channels.Pool
readonly IQueue<IChannel> store;
/**
* Creates a new instance using the {@link IChannelHealthChecker#ACTIVE}.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link IChannelPoolHandler} that will be notified for the different pool actions
*/
/// <summary>
/// Creates a new <see cref="SimpleChannelPool"/> instance using the <see cref="ChannelActiveHealthChecker"/>.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
/// <param name="handler">The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.</param>
public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler)
: this(bootstrap, handler, ChannelActiveHealthChecker.Instance)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link IChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link IChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
*/
/// <summary>
/// Creates a new <see cref="SimpleChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker)
: this(bootstrap, handler, healthChecker, true)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link IChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link IChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
* @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true};
* otherwise, channel health is only checked at acquisition time
*/
/// <summary>
/// Creates a new <see cref="SimpleChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
/// <param name="releaseHealthCheck">
/// If <c>true</c>, will check channel health before offering back. Otherwise, channel health is only checked
/// at acquisition time.
/// </param>
public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, bool releaseHealthCheck)
: this(bootstrap, handler, healthChecker, releaseHealthCheck, true)
{
}
/**
* Creates a new instance.
*
* @param bootstrap the {@link Bootstrap} that is used for connections
* @param handler the {@link IChannelPoolHandler} that will be notified for the different pool actions
* @param healthCheck the {@link IChannelHealthChecker} that will be used to check if a {@link Channel} is
* still healthy when obtain from the {@link ChannelPool}
* @param releaseHealthCheck will check channel health before offering back if this parameter set to {@code true};
* otherwise, channel health is only checked at acquisition time
* @param lastRecentUsed {@code true} {@link Channel} selection will be LIFO, if {@code false} FIFO.
*/
/// <summary>
/// Creates a new <see cref="SimpleChannelPool"/> instance.
/// </summary>
/// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
/// <param name="handler">
/// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </param>
/// <param name="healthChecker">
/// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
/// healthy when obtained from the <see cref="IChannelPool"/>.
/// </param>
/// <param name="releaseHealthCheck">
/// If <c>true</c>, will check channel health before offering back. Otherwise, channel health is only checked
/// at acquisition time.
/// </param>
/// <param name="lastRecentUsed">
/// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
/// </param>
public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, bool releaseHealthCheck, bool lastRecentUsed)
{
Contract.Requires(handler != null);
@ -102,33 +114,26 @@ namespace DotNetty.Transport.Channels.Pool
this.Handler.ChannelCreated(channel);
}
/**
* Returns the {@link Bootstrap} this pool will use to open new connections.
*
* @return the {@link Bootstrap} this pool will use to open new connections
*/
/// <summary>
/// Returns the <see cref="Bootstrapping.Bootstrap"/> this pool will use to open new connections.
/// </summary>
internal Bootstrap Bootstrap { get; }
/**
* Returns the {@link IChannelPoolHandler} that will be notified for the different pool actions.
*
* @return the {@link IChannelPoolHandler} that will be notified for the different pool actions
*/
/// <summary>
/// Returns the <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
/// </summary>
internal IChannelPoolHandler Handler { get; }
/**
* Returns the {@link IChannelHealthChecker} that will be used to check if a {@link Channel} is healthy.
*
* @return the {@link IChannelHealthChecker} that will be used to check if a {@link Channel} is healthy
*/
/// <summary>
/// Returns the <see cref="IChannelHealthChecker"/> that will be used to check if an <see cref="IChannel"/> is healthy.
/// </summary>
internal IChannelHealthChecker HealthChecker { get; }
/**
* Indicates whether this pool will check the health of channels before offering them back into the pool.
*
* @return {@code true} if this pool will check the health of channels before offering them back into the pool, or
* {@code false} if channel health is only checked at acquisition time
*/
/// <summary>
/// Indicates whether this pool will check the health of channels before offering them back into the pool.
/// Returns <c>true</c> if this pool will check the health of channels before offering them back into the pool, or
/// <c>false</c> if channel health is only checked at acquisition time.
/// </summary>
internal bool ReleaseHealthCheck { get; }
public virtual ValueTask<IChannel> AcquireAsync()
@ -198,13 +203,16 @@ namespace DotNetty.Transport.Channels.Pool
return await this.AcquireAsync();
}
}
/**
* Bootstrap a new {@link Channel}. The default implementation uses {@link Bootstrap#connect()}, sub-classes may
* override this.
* <p>
* The {@link Bootstrap} that is passed in here is cloned via {@link Bootstrap#clone()}, so it is safe to modify.
*/
/// <summary>
/// Bootstrap a new <see cref="IChannel"/>. The default implementation uses
/// <see cref="Bootstrapping.Bootstrap.ConnectAsync()"/>, sub-classes may override this.
/// </summary>
/// <param name="bs">
/// The <see cref="Bootstrapping.Bootstrap"/> instance to use to bootstrap a new <see cref="IChannel"/>.
/// The <see cref="Bootstrapping.Bootstrap"/> passed here is cloned via
/// <see cref="Bootstrapping.Bootstrap.Clone()"/>, so it is safe to modify.
/// </param>
/// <returns>The newly connected <see cref="IChannel"/>.</returns>
protected virtual Task<IChannel> ConnectChannel(Bootstrap bs) => bs.ConnectAsync();
public virtual async ValueTask<bool> ReleaseAsync(IChannel channel)
@ -278,13 +286,14 @@ namespace DotNetty.Transport.Channels.Pool
}
}
/**
* Adds the channel back to the pool only if the channel is healthy.
* @param channel the channel to put back to the pool
* @param promise offer operation promise.
* @param future the future that contains information fif channel is healthy or not.
* @throws Exception in case when failed to notify handler about release operation.
*/
/// <summary>
/// Releases the channel back to the pool only if the channel is healthy.
/// </summary>
/// <param name="channel">The <see cref="IChannel"/> to put back to the pool.</param>
/// <returns>
/// <c>true</c> if the <see cref="IChannel"/> was healthy, released, and offered back to the pool.
/// <c>false</c> if the <see cref="IChannel"/> was NOT healthy and was simply released.
/// </returns>
async ValueTask<bool> DoHealthCheckOnRelease(IChannel channel)
{
if (await this.HealthChecker.IsHealthyAsync(channel))
@ -320,22 +329,30 @@ namespace DotNetty.Transport.Channels.Pool
channel.CloseAsync();
}
/**
* Poll a {@link Channel} out of the internal storage to reuse it. This will return {@code null} if no
* {@link Channel} is ready to be reused.
*
* Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that
* implementations of these methods needs to be thread-safe!
*/
/// <summary>
/// Polls an <see cref="IChannel"/> out of the internal storage to reuse it.
/// </summary>
/// <remarks>
/// Sub-classes may override <see cref="TryPollChannel"/> and <see cref="TryOfferChannel"/>.
/// Be aware that implementations of these methods needs to be thread-safe!
/// </remarks>
/// <param name="channel">
/// An output parameter that will contain the <see cref="IChannel"/> obtained from the pool.
/// </param>
/// <returns>
/// <c>true</c> if an <see cref="IChannel"/> was retrieved from the pool, otherwise <c>false</c>.
/// </returns>
protected virtual bool TryPollChannel(out IChannel channel) => this.store.TryDequeue(out channel);
/**
* Offer a {@link Channel} back to the internal storage. This will return {@code true} if the {@link Channel}
* could be added, {@code false} otherwise.
*
* Sub-classes may override {@link #pollChannel()} and {@link #offerChannel(Channel)}. Be aware that
* implementations of these methods needs to be thread-safe!
*/
/// <summary>
/// Offers a <see cref="IChannel"/> back to the internal storage. This will return
/// </summary>
/// <remarks>
/// Sub-classes may override <see cref="TryPollChannel"/> and <see cref="TryOfferChannel"/>.
/// Be aware that implementations of these methods needs to be thread-safe!
/// </remarks>
/// <param name="channel"></param>
/// <returns><c>true</c> if the <see cref="IChannel"/> could be added, otherwise <c>false</c>.</returns>
protected virtual bool TryOfferChannel(IChannel channel) => this.store.TryEnqueue(channel);
public virtual void Dispose()

Просмотреть файл

@ -10,7 +10,7 @@ namespace DotNetty.Transport.Channels.Sockets
using DotNetty.Common.Utilities;
/// <summary>
/// {@link AbstractNioChannel} base class for {@link Channel}s that operate on bytes.
/// <see cref="AbstractSocketChannel"/> base class for <see cref="IChannel"/>s that operate on bytes.
/// </summary>
public abstract class AbstractSocketByteChannel : AbstractSocketChannel
{
@ -351,13 +351,17 @@ namespace DotNetty.Transport.Channels.Sockets
//protected abstract long doWriteFileRegion(FileRegion region);
/// <summary>
/// Read bytes into the given {@link ByteBuf} and return the amount.
/// Reads bytes into the given <see cref="IByteBuffer"/> and returns the number of bytes that were read.
/// </summary>
/// <param name="buf">The <see cref="IByteBuffer"/> to read bytes into.</param>
/// <returns>The number of bytes that were read into the buffer.</returns>
protected abstract int DoReadBytes(IByteBuffer buf);
/// <summary>Write bytes form the given <see cref="IByteBuffer"/> to the underlying <see cref="IChannel"/>.</summary>
/// <param name="buf">the <see cref="IByteBuffer"/> from which the bytes should be written</param>
/// <returns>the amount of written bytes</returns>
/// <summary>
/// Writes bytes from the given <see cref="IByteBuffer"/> to the underlying <see cref="IChannel"/>.
/// </summary>
/// <param name="buf">The <see cref="IByteBuffer"/> from which the bytes should be written.</param>
/// <returns>The number of bytes that were written from the buffer.</returns>
protected abstract int DoWriteBytes(IByteBuffer buf);
}
}

Просмотреть файл

@ -9,13 +9,15 @@ namespace DotNetty.Transport.Channels.Sockets
using System.Net.Sockets;
/// <summary>
/// {@link AbstractNioChannel} base class for {@link Channel}s that operate on messages.
/// <see cref="AbstractSocketChannel"/> base class for <see cref="IChannel"/>s that operate on messages.
/// </summary>
public abstract class AbstractSocketMessageChannel : AbstractSocketChannel
{
/// <summary>
/// @see {@link AbstractNioChannel#AbstractNioChannel(Channel, SelectableChannel, int)}
/// Creates a new <see cref="AbstractSocketMessageChannel"/> instance.
/// </summary>
/// <param name="parent">The parent <see cref="IChannel"/>. Pass <c>null</c> if there's no parent.</param>
/// <param name="socket">The <see cref="Socket"/> used by the <see cref="IChannel"/> for communication.</param>
protected AbstractSocketMessageChannel(IChannel parent, Socket socket)
: base(parent, socket)
{
@ -173,20 +175,23 @@ namespace DotNetty.Transport.Channels.Sockets
protected abstract void ScheduleMessageWrite(object message);
/// <summary>
/// Returns {@code true} if we should continue the write loop on a write error.
/// Returns <c>true</c> if we should continue the write loop on a write error.
/// </summary>
protected virtual bool ContinueOnWriteError => false;
/// <summary>
/// Read messages into the given array and return the amount which was read.
/// Reads messages into the given list and returns the amount which was read.
/// </summary>
/// <param name="buf">The list into which message objects should be inserted.</param>
/// <returns>The number of messages which were read.</returns>
protected abstract int DoReadMessages(List<object> buf);
/// <summary>
/// Write a message to the underlying {@link java.nio.channels.Channel}.
///
/// @return {@code true} if and only if the message has been written
/// Writes a message to the underlying <see cref="IChannel"/>.
/// </summary>
/// <param name="msg">The message to be written.</param>
/// <param name="input">The destination channel buffer for the message.</param>
/// <returns><c>true</c> if the message was successfully written, otherwise <c>false</c>.</returns>
protected abstract bool DoWriteMessage(object msg, ChannelOutboundBuffer input);
}
}

Просмотреть файл

@ -4,15 +4,14 @@
namespace DotNetty.Transport.Channels.Sockets
{
/// <summary>
/// Special event which will be fired and passed to the
/// {@link ChannelHandler#userEventTriggered(ChannelHandlerContext, Object)} methods once the input of
/// a {@link SocketChannel} was shutdown and the {@link SocketChannelConfig#isAllowHalfClosure()} method returns
/// {@code true}.
/// Special event which will be fired and passed to the <see cref="IChannelHandler.UserEventTriggered(IChannelHandlerContext,object)"/>
/// methods once the input of an <see cref="ISocketChannel"/> was shutdown and the
/// <see cref="ISocketChannelConfiguration.AllowHalfClosure"/> property returns <c>true</c>.
/// </summary>
public sealed class ChannelInputShutdownEvent
{
/// <summary>
/// Instance to use
/// Singleton instance to use.
/// </summary>
public static readonly ChannelInputShutdownEvent Instance = new ChannelInputShutdownEvent();

Просмотреть файл

@ -8,7 +8,7 @@ namespace DotNetty.Transport.Channels.Sockets
using System.Net.Sockets;
/// <summary>
/// The default {@link ServerSocketChannelConfig} implementation.
/// The default <see cref="IServerSocketChannelConfiguration"/> implementation.
/// </summary>
public class DefaultServerSocketChannelConfig : DefaultChannelConfiguration, IServerSocketChannelConfiguration
{

Просмотреть файл

@ -8,7 +8,7 @@ namespace DotNetty.Transport.Channels.Sockets
using System.Net.Sockets;
/// <summary>
/// The default {@link SocketChannelConfig} implementation.
/// The default <see cref="ISocketChannelConfiguration"/> implementation.
/// </summary>
public class DefaultSocketChannelConfiguration : DefaultChannelConfiguration, ISocketChannelConfiguration
{

Просмотреть файл

@ -4,7 +4,7 @@
namespace DotNetty.Transport.Channels.Sockets
{
/// <summary>
/// A TCP/IP {@link ServerChannel} which accepts incoming TCP/IP connections.
/// A TCP/IP <see cref="IServerChannel"/> which accepts incoming TCP/IP connections.
/// </summary>
public interface IServerSocketChannel : IServerChannel
{

Просмотреть файл

@ -13,8 +13,11 @@ namespace DotNetty.Transport.Channels
static readonly IInternalLogger Log = InternalLoggerFactory.GetInstance<IChannel>();
/// <summary>
/// Marks the specified {@code promise} as success. If the {@code promise} is done already, log a message.
/// Marks the specified <see cref="TaskCompletionSource"/> as success. If the
/// <see cref="TaskCompletionSource"/> is done already, logs a message.
/// </summary>
/// <param name="promise">The <see cref="TaskCompletionSource"/> to complete.</param>
/// <param name="logger">The <see cref="IInternalLogger"/> to use to log a failure message.</param>
public static void SafeSetSuccess(TaskCompletionSource promise, IInternalLogger logger)
{
if (promise != TaskCompletionSource.Void && !promise.TryComplete())
@ -24,8 +27,12 @@ namespace DotNetty.Transport.Channels
}
/// <summary>
/// Marks the specified {@code promise} as failure. If the {@code promise} is done already, log a message.
/// Marks the specified <see cref="TaskCompletionSource"/> as failure. If the
/// <see cref="TaskCompletionSource"/> is done already, log a message.
/// </summary>
/// <param name="promise">The <see cref="TaskCompletionSource"/> to complete.</param>
/// <param name="cause">The <see cref="Exception"/> to fail the <see cref="TaskCompletionSource"/> with.</param>
/// <param name="logger">The <see cref="IInternalLogger"/> to use to log a failure message.</param>
public static void SafeSetFailure(TaskCompletionSource promise, Exception cause, IInternalLogger logger)
{
if (promise != TaskCompletionSource.Void && !promise.TrySetException(cause))