/// <summary>
/// Releases the Stream's SocketAsyncEventArgs back to the pool,
/// and free's up another slot for a new client to connect
/// </summary>
/// <param name="Stream">The GamespyTcpStream object that is being released.</param>
public void Release(GamespyTcpStream Stream)
{
// If the stream has been released, then we stop here
if (!IsListening || Stream.Released)
{
return;
}
// Make sure the connection is closed properly
if (!Stream.SocketClosed)
{
Stream.Close();
return;
}
// To prevent cross instance releasing
if (!Object.ReferenceEquals(this, Stream.SocketManager))
{
throw new ArgumentException("Cannot pass a GamespyTcpStream belonging to a different TcpSocket than this one.");
}
// If we are still registered for this event, then the EventArgs should
// NEVER be disposed here, or we have an error to fix
if (Stream.DisposedEventArgs)
{
// Log this error
Program.ErrorLog.Write("WARNING: [GamespyTcpSocket.Release] Event Args were disposed imporperly!");
// Dispose old buffer tokens
BufferManager.ReleaseBuffer(Stream.ReadEventArgs);
BufferManager.ReleaseBuffer(Stream.WriteEventArgs);
// Create new Read Event Args
SocketAsyncEventArgs SockArgR = new SocketAsyncEventArgs();
BufferManager.AssignBuffer(SockArgR);
SocketReadWritePool.Push(SockArgR);
// Create new Write Event Args
SocketAsyncEventArgs SockArgW = new SocketAsyncEventArgs();
BufferManager.AssignBuffer(SockArgW);
SocketReadWritePool.Push(SockArgW);
}
else
{
// Set null's
Stream.ReadEventArgs.AcceptSocket = null;
Stream.WriteEventArgs.AcceptSocket = null;
// Get our ReadWrite AsyncEvent object back
SocketReadWritePool.Push(Stream.ReadEventArgs);
SocketReadWritePool.Push(Stream.WriteEventArgs);
}
// Now that we have another set of AsyncEventArgs, we can
// release this users Semephore lock, allowing another connection
MaxConnectionsEnforcer.Release();
}