Skip to content

Commit b0c68e6

Browse files
dsefilmor
dse
authored andcommitted
Runtime/Shutdown loop stores old caches and static variables. It's produces bugs when CPython freeing up enough objects.
1 parent af394ee commit b0c68e6

File tree

9 files changed

+53
-9
lines changed

9 files changed

+53
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2727

2828
### Fixed
2929

30+
- Fixed secondary PythonEngine.Initialize call, all sensitive static variables now reseted.
31+
This is a hidden bug. Once python cleaning up enough memory, objects from previous engine run becomes corrupted.
3032
- Fixed Visual Studio 2017 compat ([#434][i434]) for setup.py
3133
- Fixed crashes when integrating pythonnet in Unity3d ([#714][i714]),
3234
related to unloading the Application Domain

src/runtime/assemblymanager.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ internal class AssemblyManager
2424
// than it can end up referring to assemblies that are already unloaded (default behavior after unload appDomain -
2525
// unless LoaderOptimization.MultiDomain is used);
2626
// So for multidomain support it is better to have the dict. recreated for each app-domain initialization
27-
private static ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>> namespaces;
28-
27+
private static ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>> namespaces =
28+
new ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>>();
2929
//private static Dictionary<string, Dictionary<string, string>> generics;
3030
private static AssemblyLoadEventHandler lhandler;
3131
private static ResolveEventHandler rhandler;
3232

3333
// updated only under GIL?
34-
private static Dictionary<string, int> probed;
34+
private static Dictionary<string, int> probed = new Dictionary<string, int>(32);
3535

3636
// modified from event handlers below, potentially triggered from different .NET threads
3737
private static ConcurrentQueue<Assembly> assemblies;
@@ -48,10 +48,7 @@ private AssemblyManager()
4848
/// </summary>
4949
internal static void Initialize()
5050
{
51-
namespaces = new ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>>();
52-
probed = new Dictionary<string, int>(32);
53-
//generics = new Dictionary<string, Dictionary<string, string>>();
54-
assemblies = new ConcurrentQueue<Assembly>();
51+
assemblies = new AssemblyList(16);
5552
pypath = new List<string>(16);
5653

5754
AppDomain domain = AppDomain.CurrentDomain;

src/runtime/classderived.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
55
using System.Reflection.Emit;
6+
using System.Resources;
67
using System.Runtime.InteropServices;
78
using System.Threading.Tasks;
89

@@ -32,6 +33,12 @@ static ClassDerivedObject()
3233
moduleBuilders = new Dictionary<Tuple<string, string>, ModuleBuilder>();
3334
}
3435

36+
public static void Reset()
37+
{
38+
assemblyBuilders = new Dictionary<string, AssemblyBuilder>();
39+
moduleBuilders = new Dictionary<Tuple<string, string>, ModuleBuilder>();
40+
}
41+
3542
internal ClassDerivedObject(Type tp) : base(tp)
3643
{
3744
}

src/runtime/classmanager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ static ClassManager()
3434
dtype = typeof(MulticastDelegate);
3535
}
3636

37+
public static void Reset()
38+
{
39+
cache = new Dictionary<Type, ClassBase>(128);
40+
}
41+
3742
/// <summary>
3843
/// Return the ClassBase-derived instance that implements a particular
3944
/// reflected managed type, creating it if it doesn't yet exist.

src/runtime/genericutil.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Resources;
34

45
namespace Python.Runtime
56
{
@@ -20,6 +21,11 @@ static GenericUtil()
2021
mapping = new Dictionary<string, Dictionary<string, List<string>>>();
2122
}
2223

24+
public static void Reset()
25+
{
26+
mapping = new Dictionary<string, Dictionary<string, List<string>>>();
27+
}
28+
2329
/// <summary>
2430
/// Register a generic type that appears in a given namespace.
2531
/// </summary>

src/runtime/moduleobject.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,17 @@ public CLRModule() : base("clr")
335335
}
336336
}
337337

338+
public static void Reset()
339+
{
340+
hacked = false;
341+
interactive_preload = true;
342+
preload = false;
343+
344+
// XXX Test performance of new features //
345+
_SuppressDocs = false;
346+
_SuppressOverloads = false;
347+
}
348+
338349
/// <summary>
339350
/// The initializing of the preload hook has to happen as late as
340351
/// possible since sys.ps1 is created after the CLR module is

src/runtime/pyscope.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,10 +537,15 @@ public void Dispose()
537537

538538
public class PyScopeManager
539539
{
540-
public readonly static PyScopeManager Global = new PyScopeManager();
540+
public static PyScopeManager Global;
541541

542542
private Dictionary<string, PyScope> NamedScopes = new Dictionary<string, PyScope>();
543543

544+
internal static void Reset()
545+
{
546+
Global = new PyScopeManager();
547+
}
548+
544549
internal PyScope NewScope(string name)
545550
{
546551
if (name == null)

src/runtime/runtime.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,13 @@ internal static void Initialize()
281281
PyEval_InitThreads();
282282
}
283283

284+
CLRModule.Reset();
285+
GenericUtil.Reset();
286+
PyScopeManager.Reset();
287+
ClassManager.Reset();
288+
ClassDerivedObject.Reset();
289+
TypeManager.Reset();
290+
284291
IntPtr op;
285292
IntPtr dict;
286293
if (IsPython3)

src/runtime/typemanager.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ static TypeManager()
2121
cache = new Dictionary<Type, IntPtr>(128);
2222
}
2323

24+
public static void Reset()
25+
{
26+
cache = new Dictionary<Type, IntPtr>(128);
27+
}
2428

2529
/// <summary>
2630
/// Given a managed Type derived from ExtensionType, get the handle to

0 commit comments

Comments
 (0)