зеркало из https://github.com/Azure/DotNetty.git
resolved conflicts with ByteBufferUtil
integrated ChannelId with EmbeddedChannel and added DefaultChannelIdTests added copyright script and notices to all files reformatted IChannelId, ChannelGroup, and other utility methods
This commit is contained in:
Родитель
e8cb7cfda1
Коммит
02ce951b8f
|
@ -367,16 +367,6 @@ namespace DotNetty.Buffers
|
|||
return aLen - bLen;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the endianness of the specified 16-bit long integer.
|
||||
/// </summary>
|
||||
public static short SwapShort(short value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
Array.Reverse(bytes);
|
||||
return BitConverter.ToInt16(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the endianness of the specified 64-bit long integer.
|
||||
/// </summary>
|
||||
|
@ -403,16 +393,6 @@ namespace DotNetty.Buffers
|
|||
return (short)((((int)value & 0xFF) << 8) | (int)((value >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the endianness of the specified 32-bit long integer.
|
||||
/// </summary>
|
||||
public static int SwapInt(int value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
Array.Reverse(bytes);
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the given amount of bytes into a new {@link ByteBuf} that is allocated from the {@link ByteBufAllocator}.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly:InternalsVisibleTo("DotNetty.Common.Tests")]
|
||||
|
||||
[assembly:InternalsVisibleTo("DotNetty.Common.Tests")]
|
|
@ -1,29 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Utilities
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
/// String utility class.
|
||||
/// String utility class.
|
||||
/// </summary>
|
||||
public static class StringUtil
|
||||
{
|
||||
public static readonly string Newline;
|
||||
|
||||
public const char DoubleQuote = '\"';
|
||||
public const char Comma = ',';
|
||||
public const char LineFeed = '\n';
|
||||
public const char CarriageReturn = '\r';
|
||||
public const char Tab = '\t';
|
||||
|
||||
public const byte UpperCaseToLowerCaseAsciiOffset = 'a' - 'A';
|
||||
public static readonly string Newline;
|
||||
static readonly string[] Byte2HexPad = new string[256];
|
||||
static readonly string[] Byte2HexNopad = new string[256];
|
||||
|
||||
/**
|
||||
* 2 - Quote character at beginning and end.
|
||||
* 5 - Extra allowance for anticipated escape characters that may be added.
|
||||
|
@ -65,9 +64,9 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits the specified {@link String} with the specified delimiter in maxParts maximum parts.
|
||||
/// This operation is a simplified and optimized
|
||||
/// version of {@link String#split(String, int)}.
|
||||
/// Splits the specified {@link String} with the specified delimiter in maxParts maximum parts.
|
||||
/// This operation is a simplified and optimized
|
||||
/// version of {@link String#split(String, int)}.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="delim"></param>
|
||||
|
@ -130,9 +129,9 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the item after one char delim if the delim is found (else null).
|
||||
/// This operation is a simplified and optimized
|
||||
/// version of {@link String#split(String, int)}.
|
||||
/// Get the item after one char delim if the delim is found (else null).
|
||||
/// This operation is a simplified and optimized
|
||||
/// version of {@link String#split(String, int)}.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="delim"></param>
|
||||
|
@ -144,7 +143,7 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified byte value into a 2-digit hexadecimal integer.
|
||||
/// Converts the specified byte value into a 2-digit hexadecimal integer.
|
||||
/// </summary>
|
||||
public static string ByteToHexStringPadded(int value)
|
||||
{
|
||||
|
@ -165,7 +164,7 @@ namespace DotNetty.Common.Utilities
|
|||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified byte array into a hexadecimal value.
|
||||
/// Converts the specified byte array into a hexadecimal value.
|
||||
/// </summary>
|
||||
public static string ToHexStringPadded(byte[] src)
|
||||
{
|
||||
|
@ -173,7 +172,7 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified byte array into a hexadecimal value.
|
||||
/// Converts the specified byte array into a hexadecimal value.
|
||||
/// </summary>
|
||||
public static string ToHexStringPadded(byte[] src, int offset, int length)
|
||||
{
|
||||
|
@ -188,7 +187,7 @@ namespace DotNetty.Common.Utilities
|
|||
|
||||
public static StringBuilder ToHexStringPadded(StringBuilder sb, byte[] src, int offset, int length)
|
||||
{
|
||||
Contract.Requires((offset+length) <= src.Length);
|
||||
Contract.Requires((offset + length) <= src.Length);
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
{
|
||||
|
@ -198,7 +197,7 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified byte value into a hexadecimal integer.
|
||||
/// Converts the specified byte value into a hexadecimal integer.
|
||||
/// </summary>
|
||||
public static string ByteToHexString(byte value)
|
||||
{
|
||||
|
@ -226,7 +225,7 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
/// Converts the specified byte array into a hexadecimal value and appends it to the specified buffer.
|
||||
/// </summary>
|
||||
public static StringBuilder ToHexString(StringBuilder dst, byte[] src, int offset, int length)
|
||||
{
|
||||
|
@ -255,11 +254,13 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Escapes the specified value, if necessary according to
|
||||
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>.
|
||||
/// Escapes the specified value, if necessary according to
|
||||
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value which will be escaped according to
|
||||
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a></param>
|
||||
/// <param name="value">
|
||||
/// The value which will be escaped according to
|
||||
/// <a href="https://tools.ietf.org/html/rfc4180#section-2">RFC-4180</a>
|
||||
/// </param>
|
||||
/// <returns>the escaped value if necessary, or the value unchanged</returns>
|
||||
public static string EscapeCsv(string value)
|
||||
{
|
||||
|
@ -299,7 +300,6 @@ namespace DotNetty.Common.Utilities
|
|||
escaped.Append(DoubleQuote);
|
||||
escapedDoubleQuote = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LineFeed:
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Utilities
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// A collection of utility methods to retrieve and parse the values of the .Net Environment properties.
|
||||
/// A collection of utility methods to retrieve and parse the values of the .Net Environment properties.
|
||||
/// </summary>
|
||||
public static class SystemPropertyUtil
|
||||
{
|
||||
|
@ -21,7 +23,7 @@ namespace DotNetty.Common.Utilities
|
|||
|
||||
public static string Get(string key, string def)
|
||||
{
|
||||
Contract.Requires(string.IsNullOrWhiteSpace(key));
|
||||
Contract.Requires(!string.IsNullOrWhiteSpace(key));
|
||||
string value = null;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -1,47 +1,49 @@
|
|||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
[Serializable]
|
||||
public class DefaultChannelId : IChannelId
|
||||
{
|
||||
//static readonly InternalLogger logger = InternalLoggerFactory.GetInstance(typeof(DefaultChannelId));
|
||||
static readonly Regex MachineIdPattern = new Regex("^(?:[0-9a-fA-F][:-]?){6,8}$");
|
||||
const int MachineIdLen = 8;
|
||||
static readonly byte[] MachineId;
|
||||
const int ProcessIdLen = 4;
|
||||
// Maximal value for 64bit systems is 2^22. See man 5 proc.
|
||||
// See https://github.com/netty/netty/issues/2706
|
||||
const int MaxProcessId = 4194304;
|
||||
static readonly int ProcessId;
|
||||
const int SequenceLen = 4;
|
||||
const int TimestampLen = 8;
|
||||
const int RandomLen = 4;
|
||||
|
||||
static int nextSequence = 0;
|
||||
|
||||
static readonly IInternalLogger logger = InternalLoggerFactory.GetInstance<DefaultChannelId>();
|
||||
static readonly Regex MachineIdPattern = new Regex("^(?:[0-9a-fA-F][:-]?){6,8}$");
|
||||
static readonly byte[] MachineId;
|
||||
static readonly int ProcessId;
|
||||
static int nextSequence;
|
||||
static int seed = (int)(Stopwatch.GetTimestamp() & 0xFFFFFFFF); //used to safly cast long to int, because the timestamp returned is long and it doesn't fit into an int
|
||||
static readonly ThreadLocal<Random> ThreadLocalRandom = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed))); //used to simulate java ThreadLocalRandom
|
||||
|
||||
readonly byte[] data = new byte[MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen + RandomLen];
|
||||
int hashCode;
|
||||
|
||||
[NonSerialized]
|
||||
string shortValue;
|
||||
string longValue;
|
||||
|
||||
[NonSerialized]
|
||||
string longValue;
|
||||
string shortValue;
|
||||
|
||||
static DefaultChannelId()
|
||||
{
|
||||
|
@ -50,17 +52,19 @@ namespace DotNetty.Transport.Channels
|
|||
if (customProcessId != null)
|
||||
{
|
||||
if (!int.TryParse(customProcessId, out processId))
|
||||
{
|
||||
processId = -1;
|
||||
}
|
||||
}
|
||||
if (processId < 0 || processId > MaxProcessId)
|
||||
{
|
||||
processId = -1;
|
||||
//logger.warn("-Dio.netty.processId: {0} (malformed)", customProcessId);
|
||||
logger.Warn("-Dio.netty.processId: {0} (malformed)", customProcessId);
|
||||
}
|
||||
else if (logger.DebugEnabled)
|
||||
{
|
||||
logger.Debug("-Dio.netty.processId: {0} (user-set)", processId);
|
||||
}
|
||||
//else if (logger.IsDebugEnabled())
|
||||
//{
|
||||
// logger.debug("-Dio.netty.processId: {0} (user-set)", processId);
|
||||
//}
|
||||
if (processId < 0)
|
||||
{
|
||||
processId = DefaultProcessId();
|
||||
|
@ -83,11 +87,37 @@ namespace DotNetty.Transport.Channels
|
|||
MachineId = machineId;
|
||||
}
|
||||
|
||||
public string AsShortText()
|
||||
{
|
||||
string asShortText = this.shortValue;
|
||||
if (asShortText == null)
|
||||
{
|
||||
this.shortValue = asShortText = ByteBufferUtil.HexDump(this.data, MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen, RandomLen);
|
||||
}
|
||||
|
||||
return asShortText;
|
||||
}
|
||||
|
||||
public string AsLongText()
|
||||
{
|
||||
string asLongText = this.longValue;
|
||||
if (asLongText == null)
|
||||
{
|
||||
this.longValue = asLongText = this.NewLongValue();
|
||||
}
|
||||
return asLongText;
|
||||
}
|
||||
|
||||
public int CompareTo(IChannelId other)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static byte[] ParseMachineId(string value)
|
||||
{
|
||||
// Strip separators.
|
||||
value = value.Replace("[:-]", "");
|
||||
byte[] machineId = new byte[MachineIdLen];
|
||||
var machineId = new byte[MachineIdLen];
|
||||
for (int i = 0; i < value.Length; i += 2)
|
||||
{
|
||||
machineId[i] = (byte)int.Parse(value.Substring(i, i + 2), NumberStyles.AllowHexSpecifier);
|
||||
|
@ -97,8 +127,9 @@ namespace DotNetty.Transport.Channels
|
|||
|
||||
static int DefaultProcessId()
|
||||
{
|
||||
int pId = Process.GetCurrentProcess().Id;;
|
||||
|
||||
int pId = Process.GetCurrentProcess().Id;
|
||||
;
|
||||
|
||||
if (pId <= 0)
|
||||
{
|
||||
pId = ThreadLocalRandom.Value.Next(MaxProcessId + 1);
|
||||
|
@ -124,24 +155,24 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
foreach (NetworkInterface iface in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
var addrs = iface.GetIPProperties().UnicastAddresses;
|
||||
var addr = addrs.FirstOrDefault(a => !IPAddress.IsLoopback(a.Address));
|
||||
UnicastIPAddressInformationCollection addrs = iface.GetIPProperties().UnicastAddresses;
|
||||
UnicastIPAddressInformation addr = addrs.FirstOrDefault(a => !IPAddress.IsLoopback(a.Address));
|
||||
if (addr != null)
|
||||
{
|
||||
ifaces.Add(iface, addr.Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
//catch (SocketException e)
|
||||
//{
|
||||
// logger.warn("Failed to retrieve the list of available network interfaces", e);
|
||||
//}
|
||||
catch (SocketException e)
|
||||
{
|
||||
logger.Warn("Failed to retrieve the list of available network interfaces", e);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
foreach (var entry in ifaces)
|
||||
foreach (KeyValuePair<NetworkInterface, IPAddress> entry in ifaces)
|
||||
{
|
||||
NetworkInterface iface = entry.Key;
|
||||
IPAddress addr = entry.Value;
|
||||
|
@ -185,7 +216,7 @@ namespace DotNetty.Transport.Channels
|
|||
switch (bestMacAddr.Length)
|
||||
{
|
||||
case 6: // EUI-48 - convert to EUI-64
|
||||
byte[] newAddr = new byte[MachineIdLen];
|
||||
var newAddr = new byte[MachineIdLen];
|
||||
Array.Copy(bestMacAddr, 0, newAddr, 0, 3);
|
||||
newAddr[3] = 0xFF;
|
||||
newAddr[4] = 0xFE;
|
||||
|
@ -290,32 +321,6 @@ namespace DotNetty.Transport.Channels
|
|||
return 4;
|
||||
}
|
||||
|
||||
public string AsShortText()
|
||||
{
|
||||
string asShortText = this.shortValue;
|
||||
if (asShortText == null)
|
||||
{
|
||||
this.shortValue = asShortText = ByteBufferUtil.HexDump(this.data, MachineIdLen + ProcessIdLen + SequenceLen + TimestampLen, RandomLen);
|
||||
}
|
||||
|
||||
return asShortText;
|
||||
}
|
||||
|
||||
public string AsLongText()
|
||||
{
|
||||
string asLongText = this.longValue;
|
||||
if (asLongText == null)
|
||||
{
|
||||
this.longValue = asLongText = this.NewLongValue();
|
||||
}
|
||||
return asLongText;
|
||||
}
|
||||
|
||||
public int CompareTo(IChannelId other)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
string NewLongValue()
|
||||
{
|
||||
var buf = new StringBuilder(2 * this.data.Length + 5);
|
||||
|
@ -405,7 +410,7 @@ namespace DotNetty.Transport.Channels
|
|||
return false;
|
||||
}
|
||||
|
||||
return Array.Equals(this.data, ((DefaultChannelId)obj).data);
|
||||
return Equals(this.data, ((DefaultChannelId)obj).data);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
|
|
@ -41,7 +41,16 @@ namespace DotNetty.Transport.Channels.Embedded
|
|||
/// Create a new instance with an empty pipeline.
|
||||
/// </summary>
|
||||
public EmbeddedChannel()
|
||||
: this(EMPTY_HANDLERS)
|
||||
: this(EmbeddedChannelId.Instance, EMPTY_HANDLERS)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance with an empty pipeline with the specified <see cref="IChannelId"/>.
|
||||
/// </summary>
|
||||
/// <param name="channelId">The <see cref="IChannelId"/> of this channel. </param>
|
||||
public EmbeddedChannel(IChannelId channelId)
|
||||
: this(channelId, EMPTY_HANDLERS)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -52,7 +61,19 @@ namespace DotNetty.Transport.Channels.Embedded
|
|||
/// The <see cref="IChannelHandler"/>s that will be added to the <see cref="IChannelPipeline"/>
|
||||
/// </param>
|
||||
public EmbeddedChannel(params IChannelHandler[] handlers)
|
||||
: base(null)
|
||||
: this(EmbeddedChannelId.Instance, handlers)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance with the pipeline initialized with the specified handlers.
|
||||
/// </summary>
|
||||
/// <param name="id">The <see cref="IChannelId"/> of this channel.</param>
|
||||
/// <param name="handlers">
|
||||
/// The <see cref="IChannelHandler"/>s that will be added to the <see cref="IChannelPipeline"/>
|
||||
/// </param>
|
||||
public EmbeddedChannel(IChannelId id, params IChannelHandler[] handlers)
|
||||
: base(null, id)
|
||||
{
|
||||
this.config = new DefaultChannelConfiguration(this);
|
||||
if (handlers == null)
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Embedded
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// A dummy <see cref="IChannelId"/> implementation
|
||||
/// </summary>
|
||||
public sealed class EmbeddedChannelId : IChannelId
|
||||
{
|
||||
public static readonly EmbeddedChannelId Instance = new EmbeddedChannelId();
|
||||
|
||||
EmbeddedChannelId()
|
||||
{
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is EmbeddedChannelId;
|
||||
}
|
||||
|
||||
public int CompareTo(IChannelId other)
|
||||
{
|
||||
if (other is EmbeddedChannelId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return string.Compare(this.AsLongText(), other.AsLongText(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "embedded";
|
||||
}
|
||||
|
||||
public string AsShortText()
|
||||
{
|
||||
return this.ToString();
|
||||
}
|
||||
|
||||
public string AsLongText()
|
||||
{
|
||||
return this.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
public class ChannelGroupException : ChannelException, IEnumerable<KeyValuePair<IChannel, Exception>>
|
||||
{
|
||||
readonly IReadOnlyCollection<KeyValuePair<IChannel, Exception>> failed;
|
||||
|
@ -26,7 +30,7 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
return this.failed.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.failed.GetEnumerator();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using System;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System;
|
||||
|
||||
public static class ChannelMatchers
|
||||
{
|
||||
static readonly IChannelMatcher AllMatcher = new AllChannelMatcher();
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
public sealed class CombinedEnumerator<E> : IEnumerator<E>
|
||||
|
@ -29,7 +32,7 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
this.currentEnumerator.Dispose();
|
||||
}
|
||||
|
||||
object System.Collections.IEnumerator.Current
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return this.Current; }
|
||||
}
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Utilities;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
public class DefaultChannelGroup : IChannelGroup
|
||||
{
|
||||
static int nextId = 0;
|
||||
readonly string name;
|
||||
static int nextId;
|
||||
readonly IEventExecutor executor;
|
||||
readonly ConcurrentDictionary<IChannelId, IChannel> serverChannels = new ConcurrentDictionary<IChannelId, IChannel>();
|
||||
readonly string name;
|
||||
readonly ConcurrentDictionary<IChannelId, IChannel> nonServerChannels = new ConcurrentDictionary<IChannelId, IChannel>();
|
||||
readonly ConcurrentDictionary<IChannelId, IChannel> serverChannels = new ConcurrentDictionary<IChannelId, IChannel>();
|
||||
|
||||
public DefaultChannelGroup(IEventExecutor executor)
|
||||
: this(string.Format("group-{0:X2}", Interlocked.Increment(ref nextId)), executor)
|
||||
|
@ -33,6 +37,11 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
this.executor = executor;
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
get { return this.serverChannels.Count == 0 && this.nonServerChannels.Count == 0; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return this.name; }
|
||||
|
@ -77,22 +86,6 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
return new DefaultChannelGroupCompletionSource(this, futures /*, this.executor*/).Task;
|
||||
}
|
||||
|
||||
static object SafeDuplicate(object message)
|
||||
{
|
||||
if (message is IByteBuffer)
|
||||
{
|
||||
return ((IByteBuffer)message).Duplicate().Retain();
|
||||
}
|
||||
else if (message is IByteBufferHolder)
|
||||
{
|
||||
return ((IByteBufferHolder)message).Duplicate().Retain();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReferenceCountUtil.Retain(message);
|
||||
}
|
||||
}
|
||||
|
||||
public IChannelGroup Flush(IChannelMatcher matcher)
|
||||
{
|
||||
foreach (IChannel c in this.nonServerChannels.Values)
|
||||
|
@ -121,27 +114,6 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
return this.GetHashCode() - other.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}(name: {1}, size: {2})", this.GetType().Name, this.Name, this.Count);
|
||||
}
|
||||
|
||||
public bool Add(IChannel channel)
|
||||
{
|
||||
var map = channel is IServerChannel ? this.serverChannels : this.nonServerChannels;
|
||||
bool added = map.TryAdd(channel.Id, channel);
|
||||
if (added)
|
||||
{
|
||||
channel.CloseCompletion.ContinueWith(x => this.Remove(channel));
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
void ICollection<IChannel>.Add(IChannel item)
|
||||
{
|
||||
this.Add(item);
|
||||
|
@ -169,20 +141,6 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
public void CopyTo(IChannel[] array, int arrayIndex)
|
||||
{
|
||||
this.ToArray().CopyTo(array, arrayIndex);
|
||||
|
||||
}
|
||||
|
||||
public IChannel[] ToArray()
|
||||
{
|
||||
var channels = new List<IChannel>(this.Count);
|
||||
channels.AddRange(this.serverChannels.Values);
|
||||
channels.AddRange(this.nonServerChannels.Values);
|
||||
return channels.ToArray();
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
get { return this.serverChannels.Count == 0 && this.nonServerChannels.Count == 0; }
|
||||
}
|
||||
|
||||
public int Count
|
||||
|
@ -208,47 +166,13 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
}
|
||||
}
|
||||
|
||||
public bool Remove(IChannelId channelId)
|
||||
{
|
||||
IChannel ch = null;
|
||||
|
||||
if (this.serverChannels.TryRemove(channelId, out ch))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (this.nonServerChannels.TryRemove(channelId, out ch))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Remove(object o)
|
||||
{
|
||||
var id = o as IChannelId;
|
||||
if (id != null)
|
||||
{
|
||||
return this.Remove(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = o as IChannel;
|
||||
if (channel != null)
|
||||
{
|
||||
return this.Remove(channel);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerator<IChannel> GetEnumerator()
|
||||
{
|
||||
return new CombinedEnumerator<IChannel>(this.serverChannels.Values.GetEnumerator(),
|
||||
this.nonServerChannels.Values.GetEnumerator());
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return new CombinedEnumerator<IChannel>(this.serverChannels.Values.GetEnumerator(),
|
||||
this.nonServerChannels.Values.GetEnumerator());
|
||||
|
@ -383,5 +307,84 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
|
||||
return new DefaultChannelGroupCompletionSource(this, futures /*, this.executor*/).Task;
|
||||
}
|
||||
|
||||
static object SafeDuplicate(object message)
|
||||
{
|
||||
if (message is IByteBuffer)
|
||||
{
|
||||
return ((IByteBuffer)message).Duplicate().Retain();
|
||||
}
|
||||
else if (message is IByteBufferHolder)
|
||||
{
|
||||
return ((IByteBufferHolder)message).Duplicate().Retain();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReferenceCountUtil.Retain(message);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}(name: {1}, size: {2})", this.GetType().Name, this.Name, this.Count);
|
||||
}
|
||||
|
||||
public bool Add(IChannel channel)
|
||||
{
|
||||
ConcurrentDictionary<IChannelId, IChannel> map = channel is IServerChannel ? this.serverChannels : this.nonServerChannels;
|
||||
bool added = map.TryAdd(channel.Id, channel);
|
||||
if (added)
|
||||
{
|
||||
channel.CloseCompletion.ContinueWith(x => this.Remove(channel));
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
public IChannel[] ToArray()
|
||||
{
|
||||
var channels = new List<IChannel>(this.Count);
|
||||
channels.AddRange(this.serverChannels.Values);
|
||||
channels.AddRange(this.nonServerChannels.Values);
|
||||
return channels.ToArray();
|
||||
}
|
||||
|
||||
public bool Remove(IChannelId channelId)
|
||||
{
|
||||
IChannel ch = null;
|
||||
|
||||
if (this.serverChannels.TryRemove(channelId, out ch))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (this.nonServerChannels.TryRemove(channelId, out ch))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Remove(object o)
|
||||
{
|
||||
var id = o as IChannelId;
|
||||
if (id != null)
|
||||
{
|
||||
return this.Remove(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = o as IChannel;
|
||||
if (channel != null)
|
||||
{
|
||||
return this.Remove(channel);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +1,21 @@
|
|||
using DotNetty.Common.Concurrency;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading.Tasks;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class DefaultChannelGroupCompletionSource : TaskCompletionSource<int>, IChannelGroupTaskCompletionSource
|
||||
{
|
||||
readonly IChannelGroup group;
|
||||
readonly Dictionary<IChannel, Task> futures;
|
||||
int successCount;
|
||||
readonly IChannelGroup group;
|
||||
int failureCount;
|
||||
int successCount;
|
||||
|
||||
public DefaultChannelGroupCompletionSource(IChannelGroup group, Dictionary<IChannel, Task> futures /*, IEventExecutor executor*/)
|
||||
: this(group, futures /*,executor*/, null)
|
||||
|
@ -26,7 +29,7 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
Contract.Requires(futures != null);
|
||||
|
||||
this.group = group;
|
||||
foreach (var pair in futures)
|
||||
foreach (KeyValuePair<IChannel, Task> pair in futures)
|
||||
{
|
||||
this.futures.Add(pair.Key, pair.Value);
|
||||
pair.Value.ContinueWith(x =>
|
||||
|
@ -128,7 +131,7 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
this.futures.Values.GetEnumerator().Dispose();
|
||||
}
|
||||
|
||||
object System.Collections.IEnumerator.Current
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get { return this.futures.Values.GetEnumerator().Current; }
|
||||
}
|
||||
|
@ -140,7 +143,7 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
|
||||
public void Reset()
|
||||
{
|
||||
((System.Collections.IEnumerator)this.futures.Values.GetEnumerator()).Reset();
|
||||
((IEnumerator)this.futures.Values.GetEnumerator()).Reset();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public interface IChannelGroup : ICollection<IChannel>, IComparable<IChannelGroup>
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the name of this group. A group name is purely for helping
|
||||
/// you to distinguish one group from others.
|
||||
/// Returns the name of this group. A group name is purely for helping
|
||||
/// you to distinguish one group from others.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public interface IChannelGroupTaskCompletionSource : IEnumerator<Task>
|
||||
{
|
||||
IChannelGroup Group { get; }
|
||||
|
||||
ChannelGroupException Cause { get; }
|
||||
|
||||
Task Find(IChannel channel);
|
||||
|
||||
bool IsPartialSucess();
|
||||
|
@ -14,7 +19,5 @@ namespace DotNetty.Transport.Channels.Groups
|
|||
bool IsSucess();
|
||||
|
||||
bool IsPartialFailure();
|
||||
|
||||
ChannelGroupException Cause { get; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
namespace DotNetty.Transport.Channels.Groups
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels.Groups
|
||||
{
|
||||
public interface IChannelMatcher
|
||||
{
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
using System;
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels
|
||||
{
|
||||
using System;
|
||||
|
||||
public interface IChannelId : IComparable<IChannelId>
|
||||
{
|
||||
string AsShortText();
|
||||
|
||||
string AsLongText();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@
|
|||
<Compile Include="Channels\DefaultChannelPipeline.cs" />
|
||||
<Compile Include="Channels\DefaultMessageSizeEstimator.cs" />
|
||||
<Compile Include="Channels\Embedded\EmbeddedChannel.cs" />
|
||||
<Compile Include="Channels\Embedded\EmbeddedChannelId.cs" />
|
||||
<Compile Include="Channels\Embedded\EmbeddedEventLoop.cs" />
|
||||
<Compile Include="Channels\Embedded\EmbeddedSocketAddress.cs" />
|
||||
<Compile Include="Channels\FixedRecvByteBufAllocator.cs" />
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
// <auto-generated/>
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
// <auto-generated/>
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyCompanyAttribute("DotNetty")]
|
||||
[assembly: AssemblyCopyrightAttribute("Copyright © 2015")]
|
||||
[assembly: AssemblyVersionAttribute("0.1.3")]
|
||||
[assembly: AssemblyFileVersionAttribute("0.1.3")]
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Tests.Channel
|
||||
{
|
||||
using System.Text.RegularExpressions;
|
||||
using DotNetty.Transport.Channels;
|
||||
using Xunit;
|
||||
|
||||
public class DefaulChannelIdTest
|
||||
{
|
||||
[Fact]
|
||||
public void TestShortText()
|
||||
{
|
||||
string text = DefaultChannelId.NewInstance().AsShortText();
|
||||
Assert.True(Regex.IsMatch(text, @"^[0-9a-f]{8}$"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestLongText()
|
||||
{
|
||||
string text = DefaultChannelId.NewInstance().AsLongText();
|
||||
Assert.True(Regex.IsMatch(text, @"^[0-9a-f]{16}-[0-9a-f]{8}-[0-9a-f]{8}-[0-9a-f]{16}-[0-9a-f]{8}$"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIdempotentMachineId()
|
||||
{
|
||||
string a = DefaultChannelId.NewInstance().AsLongText().Substring(0, 8);
|
||||
string b = DefaultChannelId.NewInstance().AsLongText().Substring(0, 8);
|
||||
Assert.Equal(a, b);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIdempotentProcessId()
|
||||
{
|
||||
string a = DefaultChannelId.NewInstance().AsLongText().Substring(9, 4);
|
||||
string b = DefaultChannelId.NewInstance().AsLongText().Substring(9, 4);
|
||||
Assert.Equal(a, b);
|
||||
}
|
||||
|
||||
// TODO: port TestSerialization https://github.com/netty/netty/blob/master/transport/src/test/java/io/netty/channel/DefaultChannelIdTest.java
|
||||
// requires ByteBufOutputStream and InputStream
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@
|
|||
<Otherwise />
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="Channel\DefaulChannelIdTest.cs" />
|
||||
<Compile Include="Channel\Embedded\EmbeddedChannelTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
$lineBreak = "`r`n"
|
||||
$noticeTemplate = "// Copyright (c) Microsoft. All rights reserved.$lineBreak// Licensed under the MIT license. See LICENSE file in the project root for full license information.$lineBreak$lineBreak"
|
||||
$tokenToReplace = [regex]::Escape("[FileName]")
|
||||
|
||||
Function CreateFileSpecificNotice($sourcePath){
|
||||
$fileName = Split-Path $sourcePath -Leaf
|
||||
$fileSpecificNotice = $noticeTemplate -replace $tokenToReplace, $fileName
|
||||
return $fileSpecificNotice
|
||||
}
|
||||
|
||||
Function SourceFileContainsNotice($sourcePath){
|
||||
$copyrightSnippet = [regex]::Escape("// Copyright (c) Microsoft")
|
||||
|
||||
$fileSpecificNotice = CreateFileSpecificNotice($sourcePath)
|
||||
$arrMatchResults = Get-Content $sourcePath | Select-String $copyrightSnippet
|
||||
|
||||
if ($arrMatchResults -ne $null -and $arrMatchResults.count -gt 0){
|
||||
return $true
|
||||
}
|
||||
else{
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
Function AddHeaderToSourceFile($sourcePath) {
|
||||
# "Source path is: $sourcePath"
|
||||
|
||||
$containsNotice = SourceFileContainsNotice($sourcePath)
|
||||
# "Contains notice: $containsNotice"
|
||||
|
||||
if ($containsNotice){
|
||||
#"Source file already contains notice -- not adding"
|
||||
}
|
||||
else {
|
||||
#"Source file does not contain notice -- adding"
|
||||
$noticeToInsert = CreateFileSpecificNotice($sourcePath)
|
||||
|
||||
$fileLines = (Get-Content $sourcePath) -join $lineBreak
|
||||
|
||||
$content = $noticeToInsert + $fileLines + $lineBreak
|
||||
|
||||
$content | Out-File $sourcePath -Encoding utf8
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
|
||||
$parent = (get-item $scriptPath).Parent.FullName
|
||||
$startingPath = "$parent\src"
|
||||
Get-ChildItem $startingPath\*.cs -Recurse | Select FullName | Foreach-Object { AddHeaderToSourceFile($_.FullName)}
|
||||
Get-ChildItem $startingPath\*.fs -Recurse | Select FullName | Foreach-Object { AddHeaderToSourceFile($_.FullName)}
|
Загрузка…
Ссылка в новой задаче