i knew it was a lock

ross
This commit is contained in:
Malloc of Kuzkycyziklistan 2017-05-03 16:10:50 -05:00
parent e8bf127297
commit 643ac0bba6
4 changed files with 44 additions and 30 deletions

View file

@ -7,6 +7,7 @@ using System.Threading.Tasks;
namespace Kneesocks { namespace Kneesocks {
public abstract class Connection { public abstract class Connection {
public UInt64 Id { get; private set; }
private TcpClient Socket; private TcpClient Socket;
private NetworkStream Stream; private NetworkStream Stream;
@ -18,13 +19,15 @@ namespace Kneesocks {
private Dictionary<string, string> Headers = private Dictionary<string, string> Headers =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
public Connection(TcpClient sock) { protected Connection(UInt64 id, TcpClient sock) {
Id = id;
Socket = sock; Socket = sock;
Socket.ReceiveTimeout = 1; Socket.ReceiveTimeout = 1;
Stream = sock.GetStream(); Stream = sock.GetStream();
} }
public Connection(Connection conn) { protected Connection(Connection conn) {
Id = conn.Id;
Socket = conn.Socket; Socket = conn.Socket;
Stream = Socket.GetStream(); Stream = Socket.GetStream();

View file

@ -15,6 +15,7 @@ namespace Kneesocks {
// a new thread is created // a new thread is created
public int SizeGrowth { get; set; } = 1; public int SizeGrowth { get; set; } = 1;
// maximum amount of connections that a single thread will be assigned // maximum amount of connections that a single thread will be assigned
// 0 means no limit
public int MaxSize { get; set; } = 10; public int MaxSize { get; set; } = 10;
// maximum number of threads that will be spawned // maximum number of threads that will be spawned
// 0 means no limit // 0 means no limit
@ -30,46 +31,57 @@ namespace Kneesocks {
private List<ThreadContext> Threads private List<ThreadContext> Threads
= new List<ThreadContext>(); = new List<ThreadContext>();
private UInt64 InternalCounter = 0;
private Dictionary<UInt64, Connection> Connections private Dictionary<UInt64, Connection> Connections
= new Dictionary<UInt64, Connection>(); = new Dictionary<UInt64, Connection>();
private List<ThreadContext> InvalidThreads
= new List<ThreadContext>();
private Mutex InvalidThreadsMutex = new Mutex();
public Pool() { public Pool() {
for(var i = 0; i < InitialCount; ++i) for(var i = 0; i < InitialCount; ++i)
CreateThread(); CreateThread();
} }
public bool AddConnection(Connection connection) { private void IndexConnection(UInt64 id, Connection connection) {
if(InvalidThreads.Count > 0) { lock(Connections) {
foreach(var invalidThread in InvalidThreads) if(id == 0)
Threads.RemoveAll(x => Object.ReferenceEquals(invalidThread, x)); id = InternalCounter++;
updateFullThreadCount = true; Connections.Add(id, connection);
InvalidThreads.RemoveAll(x => true);
} }
}
foreach(var thread in Threads) { public bool AddConnection(Connection connection, UInt64 id = 0) {
if(thread.Stack.Count < FullThreadSize) { lock(Threads) {
thread.Stack.AddClient(connection); foreach(var thread in Threads) {
if(thread.Stack.Count < FullThreadSize) {
thread.Stack.AddClient(connection);
return true;
}
}
if(MaxCount == 0 || Threads.Count < MaxCount) {
CreateThread(connection);
return true; return true;
} }
} }
if(MaxCount == 0 || Threads.Count < MaxCount) {
CreateThread(connection);
return true;
}
return false; return false;
} }
public void InvalidateConnection(Connection connection) {
lock(Connections) {
}
}
public void InvalidateThread(Stack<T> stackRef) { public void InvalidateThread(Stack<T> stackRef) {
var ctx = Threads.FirstOrDefault(x => Object.ReferenceEquals(x.Stack, stackRef)); lock(Threads) {
if(ctx != null) var ctx = Threads.FirstOrDefault(x => Object.ReferenceEquals(x.Stack, stackRef));
InvalidThreads.Add(ctx); if(ctx != null) {
Threads.Remove(ctx);
updateFullThreadCount = true;
}
}
} }
private ThreadContext CreateThread(Connection initialConnection = null, bool runWithNoClients = false) { private ThreadContext CreateThread(Connection initialConnection = null, bool runWithNoClients = false) {
@ -78,7 +90,7 @@ namespace Kneesocks {
Stack = stack, Stack = stack,
Thread = new Thread(new ThreadStart(stack.ManageStack)) Thread = new Thread(new ThreadStart(stack.ManageStack))
}; };
Threads.Add(ctx); Threads.Add(ctx);
updateFullThreadCount = true; updateFullThreadCount = true;
return ctx; return ctx;
@ -88,7 +100,7 @@ namespace Kneesocks {
get { get {
if(updateFullThreadCount) { if(updateFullThreadCount) {
_fullThreadCount = Math.Min( _fullThreadCount = Math.Min(
MaxSize, MaxSize == 0 ? int.MaxValue : MaxSize,
InitialSize + SizeGrowth * (Threads.Count - InitialCount) InitialSize + SizeGrowth * (Threads.Count - InitialCount)
); );
} }

View file

@ -4,11 +4,10 @@ using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kneesocks;
namespace CircleScape { namespace CircleScape {
class ActiveConnection : Connection { class ActiveConnection : Kneesocks.Connection {
public ActiveConnection(TcpClient sock) : base(sock) { } public ActiveConnection(UInt32 id, TcpClient sock) : base(id, sock) { }
public ActiveConnection(PendingConnection conn) : base(conn) { } public ActiveConnection(PendingConnection conn) : base(conn) { }
} }

View file

@ -6,7 +6,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CircleScape { namespace CircleScape {
class PendingConnection : ActiveConnection { class PendingConnection : Kneesocks.Connection {
public PendingConnection(TcpClient sock) : base(sock) { } public PendingConnection(UInt32 id, TcpClient sock) : base(id, sock) { }
} }
} }