From fe1723af69b9ca92f39d4ff012fb2088883114da Mon Sep 17 00:00:00 2001 From: Gabriele Gervasi Date: Tue, 18 Oct 2022 15:37:32 +0200 Subject: [PATCH 1/2] Fix unloading --- MySQL.Data/src/MySql.Data.csproj | 36 ++++++++++++++++++++ MySQL.Data/src/MySqlPoolManager.cs | 54 ++++++++++++++++++++++++++---- MySQL.Data/src/common/DnsSrv.cs | 1 - 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/MySQL.Data/src/MySql.Data.csproj b/MySQL.Data/src/MySql.Data.csproj index c224d4ea8..22d87ac17 100644 --- a/MySQL.Data/src/MySql.Data.csproj +++ b/MySQL.Data/src/MySql.Data.csproj @@ -129,6 +129,42 @@ + + + 4.3.0 + + + + + + 4.3.0 + + + + + + 4.3.0 + + + + + + 4.3.0 + + + + + + 4.3.0 + + + + + + 4.3.0 + + + $(ProjectDir)Properties\metadata.sh $(ConfigurationName) $(Version) diff --git a/MySQL.Data/src/MySqlPoolManager.cs b/MySQL.Data/src/MySqlPoolManager.cs index 2d759f3dd..2572a9baa 100644 --- a/MySQL.Data/src/MySqlPoolManager.cs +++ b/MySQL.Data/src/MySqlPoolManager.cs @@ -32,6 +32,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Reflection; +using System.Runtime.Loader; using System.Threading; @@ -46,20 +48,24 @@ internal class MySqlPoolManager private static readonly List ClearingPools = new List(); internal const int DEMOTED_TIMEOUT = 120000; - #region Properties +#region Properties + /// /// Queue of demoted hosts. /// internal static ConcurrentQueue DemotedHosts { get; set; } + /// /// List of hosts that will be attempted to connect to. /// internal static List Hosts { get; set; } + /// /// Timer to be used when a host have been demoted. /// internal static Timer DemotedServersTimer { get; set; } - #endregion + +#endregion // Timeout in seconds, after which an unused (idle) connection // should be closed. @@ -67,16 +73,52 @@ internal class MySqlPoolManager static MySqlPoolManager() { - AppDomain.CurrentDomain.ProcessExit += EnsureClearingPools; - AppDomain.CurrentDomain.DomainUnload += EnsureClearingPools; + AppDomain.CurrentDomain.ProcessExit += Unload; + AppDomain.CurrentDomain.DomainUnload += Unload; + AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += DefaultOnUnloading; + } + + private static void DefaultOnUnloading(AssemblyLoadContext obj) + { + _Unload(); } - private static void EnsureClearingPools(object sender, EventArgs e) + private static void Unload(object sender, EventArgs e) + { + _Unload(); + } + + private static void _Unload() { ClearAllPools(); + timer?.Dispose(); + try + { + AppDomain.CurrentDomain.ProcessExit -= Unload; + } + catch + { + } + + try + { + AppDomain.CurrentDomain.DomainUnload -= Unload; + } + catch + { + } + + try + { + AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading -= DefaultOnUnloading; + } + catch + { + } + } - // we add a small amount to the due time to let the cleanup detect + // we add a small amount to the due time to let the cleanup detect //expired connections in the first cleanup. private static Timer timer = new Timer(CleanIdleConnections, null, (maxConnectionIdleTime * 1000) + 8000, maxConnectionIdleTime * 1000); diff --git a/MySQL.Data/src/common/DnsSrv.cs b/MySQL.Data/src/common/DnsSrv.cs index 1be6f97bc..dae4c1d65 100644 --- a/MySQL.Data/src/common/DnsSrv.cs +++ b/MySQL.Data/src/common/DnsSrv.cs @@ -119,7 +119,6 @@ internal static List SortSrvRecords(List srvRecords) /// private static void Reset() { - if (_resolver != null) _resolver = null; } } From ff92316973db9c72f705c4603e87792e60e9a2da Mon Sep 17 00:00:00 2001 From: Gabriele Gervasi Date: Tue, 18 Oct 2022 15:29:41 +0200 Subject: [PATCH 2/2] Fix unloading --- MySQL.Data/src/MySqlPoolManager.cs | 47 +++++++++++------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/MySQL.Data/src/MySqlPoolManager.cs b/MySQL.Data/src/MySqlPoolManager.cs index 2572a9baa..108eac528 100644 --- a/MySQL.Data/src/MySqlPoolManager.cs +++ b/MySQL.Data/src/MySqlPoolManager.cs @@ -33,8 +33,10 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Runtime.Loader; using System.Threading; +#if !NET452 +using System.Runtime.Loader; +#endif namespace MySql.Data.MySqlClient @@ -73,17 +75,21 @@ internal class MySqlPoolManager static MySqlPoolManager() { - AppDomain.CurrentDomain.ProcessExit += Unload; - AppDomain.CurrentDomain.DomainUnload += Unload; - AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += DefaultOnUnloading; + AppDomain.CurrentDomain.ProcessExit += UnloadAppDomain; + AppDomain.CurrentDomain.DomainUnload += UnloadAppDomain; +#if !NET452 + AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += UnloadAssemblyLoadContext; +#endif } - private static void DefaultOnUnloading(AssemblyLoadContext obj) +#if !NET452 + private static void UnloadAssemblyLoadContext(AssemblyLoadContext obj) { _Unload(); } +#endif - private static void Unload(object sender, EventArgs e) + private static void UnloadAppDomain(object sender, EventArgs e) { _Unload(); } @@ -92,30 +98,11 @@ private static void _Unload() { ClearAllPools(); timer?.Dispose(); - try - { - AppDomain.CurrentDomain.ProcessExit -= Unload; - } - catch - { - } - - try - { - AppDomain.CurrentDomain.DomainUnload -= Unload; - } - catch - { - } - - try - { - AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading -= DefaultOnUnloading; - } - catch - { - } - + AppDomain.CurrentDomain.ProcessExit -= UnloadAppDomain; + AppDomain.CurrentDomain.DomainUnload -= UnloadAppDomain; +#if !NET452 + AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading -= UnloadAssemblyLoadContext; +#endif } // we add a small amount to the due time to let the cleanup detect