replace beginaccept

This commit is contained in:
UbitUmarov
2024-04-28 10:58:27 +01:00
parent 943ea29419
commit 034cf66dfe
3 changed files with 94 additions and 59 deletions

View File

@@ -30,6 +30,7 @@ using System;
using System.Threading; using System.Threading;
using System.Collections.Generic; using System.Collections.Generic;
using Timer = System.Threading.Timer; using Timer = System.Threading.Timer;
using System.Runtime.InteropServices;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
@@ -460,6 +461,59 @@ namespace OpenSim.Framework
return success; return success;
} }
public ref TValue1 TryGetOrDefaultValue(TKey1 key, out bool existed)
{
bool gotLock = false;
try
{
try { }
finally
{
m_rwLock.ExitUpgradeableReadLock();
gotLock = true;
}
return ref CollectionsMarshal.GetValueRefOrAddDefault(m_values, key, out existed);
}
finally
{
if (gotLock)
m_rwLock.ExitUpgradeableReadLock();
}
}
public ref TValue1 TryGetOrDefaultValue(TKey1 key, int expireMS, out bool existed)
{
bool gotLock = false;
try
{
try { }
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
}
ref TValue1 ret = ref CollectionsMarshal.GetValueRefOrAddDefault(m_values, key, out existed);
int now;
if (expireMS > 0)
{
expireMS = (expireMS > m_expire) ? expireMS : m_expire;
now = (int)(Util.GetTimeStampMS() - m_startTS) + expireMS;
}
else
now = int.MinValue;
m_expireControl[key] = now;
return ref ret;
}
finally
{
if (gotLock)
m_rwLock.EnterWriteLock();
}
}
public TValue1[] Values public TValue1[] Values
{ {
get get

View File

@@ -322,7 +322,7 @@ namespace OSHttpServer
default: default:
return; return;
} }
m_processWaitEven.Set(); m_processWaitEven?.Set();
} }
public static void PulseWaitSend() public static void PulseWaitSend()

View File

@@ -5,6 +5,8 @@ using System.Net.Security;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace OSHttpServer namespace OSHttpServer
{ {
@@ -19,8 +21,8 @@ namespace OSHttpServer
private TcpListener m_listener; private TcpListener m_listener;
private ILogWriter m_logWriter = NullLogWriter.Instance; private ILogWriter m_logWriter = NullLogWriter.Instance;
private int m_pendingAccepts;
private bool m_shutdown; private bool m_shutdown;
public readonly CancellationTokenSource m_CancellationSource = new();
protected RemoteCertificateValidationCallback m_clientCertValCallback = null; protected RemoteCertificateValidationCallback m_clientCertValCallback = null;
public event EventHandler<ClientAcceptedEventArgs> Accepted; public event EventHandler<ClientAcceptedEventArgs> Accepted;
@@ -86,6 +88,7 @@ namespace OSHttpServer
return new OSHttpListener(address, port, certificate, protocols); return new OSHttpListener(address, port, certificate, protocols);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void OnRequestReceived(object sender, RequestEventArgs e) private void OnRequestReceived(object sender, RequestEventArgs e)
{ {
RequestReceived?.Invoke(sender, e); RequestReceived?.Invoke(sender, e);
@@ -120,76 +123,53 @@ namespace OSHttpServer
/// </summary> /// </summary>
public bool UseTraceLogs { get; set; } public bool UseTraceLogs { get; set; }
private async void AcceptLoop()
/// <exception cref="Exception"><c>Exception</c>.</exception>
private void OnAccept(IAsyncResult ar)
{ {
bool beginAcceptCalled = false;
try try
{ {
int count = Interlocked.Decrement(ref m_pendingAccepts); while (true)
if (m_shutdown)
{ {
if (count == 0) if (m_shutdown)
{
m_shutdownEvent.Set(); m_shutdownEvent.Set();
return; break;
} }
Interlocked.Increment(ref m_pendingAccepts); Socket socket = await m_listener.AcceptSocketAsync(m_CancellationSource.Token).ConfigureAwait(false); ;
m_listener.BeginAcceptSocket(OnAccept, null); if (!socket.Connected)
beginAcceptCalled = true; {
Socket socket = m_listener.EndAcceptSocket(ar); socket.Dispose();
if (!socket.Connected) continue;
{ }
socket.Dispose();
return;
}
socket.NoDelay = true; socket.NoDelay = true;
if (!OnAcceptingSocket(socket)) if (!OnAcceptingSocket(socket))
{ {
socket.Disconnect(true); socket.Disconnect(true);
return; continue;
} }
if (socket.Connected)
{
m_logWriter.Write(this, LogPrio.Debug, $"Accepted connection from: {socket.RemoteEndPoint}");
if(socket.Connected) if (m_certificate is not null)
{ m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocols, m_clientCertValCallback);
m_logWriter.Write(this, LogPrio.Debug, $"Accepted connection from: {socket.RemoteEndPoint}"); else
m_contextFactory.CreateContext(socket);
if (m_certificate is not null) }
m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocols, m_clientCertValCallback);
else else
m_contextFactory.CreateContext(socket); socket.Dispose();
} }
else }
socket.Dispose(); catch (OperationCanceledException)
{
m_shutdownEvent.Set();
} }
catch (Exception err) catch (Exception err)
{ {
m_logWriter.Write(this, LogPrio.Debug, err.Message); m_logWriter.Write(this, LogPrio.Debug, err.Message);
ExceptionThrown?.Invoke(this, err); ExceptionThrown?.Invoke(this, err);
if (!beginAcceptCalled)
RetryBeginAccept();
}
}
/// <summary>
/// Will try to accept connections one more time.
/// </summary>
/// <exception cref="Exception">If any exceptions is thrown.</exception>
private void RetryBeginAccept()
{
try
{
m_logWriter.Write(this, LogPrio.Error, "Trying to accept connections again.");
m_listener.BeginAcceptSocket(OnAccept, null);
}
catch (Exception err)
{
m_logWriter.Write(this, LogPrio.Fatal, err.Message);
ExceptionThrown?.Invoke(this, err);
} }
} }
@@ -221,8 +201,7 @@ namespace OSHttpServer
m_listener = new TcpListener(m_address, m_port); m_listener = new TcpListener(m_address, m_port);
m_listener.Start(backlog); m_listener.Start(backlog);
Interlocked.Increment(ref m_pendingAccepts); Task.Run(AcceptLoop).ConfigureAwait(false);
m_listener.BeginAcceptSocket(OnAccept, null);
} }
/// <summary> /// <summary>
@@ -232,10 +211,11 @@ namespace OSHttpServer
public void Stop() public void Stop()
{ {
m_shutdown = true; m_shutdown = true;
m_CancellationSource.Cancel();
m_contextFactory.Shutdown(); m_contextFactory.Shutdown();
m_listener.Stop();
if (!m_shutdownEvent.WaitOne()) if (!m_shutdownEvent.WaitOne())
m_logWriter.Write(this, LogPrio.Error, "Failed to shutdown listener properly."); m_logWriter.Write(this, LogPrio.Error, "Failed to shutdown listener properly.");
m_listener.Stop();
m_listener = null; m_listener = null;
Dispose(); Dispose();
} }
@@ -251,6 +231,7 @@ namespace OSHttpServer
if (m_shutdownEvent != null) if (m_shutdownEvent != null)
{ {
m_shutdownEvent.Dispose(); m_shutdownEvent.Dispose();
m_CancellationSource.Dispose();
} }
} }
} }