Skip to content

Track Runtime run number #1074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 23, 2021
Prev Previous commit
Next Next commit
dispose registered codecs and interop configuration during shutdown
  • Loading branch information
lostmsu committed Nov 12, 2021
commit 62e2fb45eebac0a01bb4df4ed8f276c4e4d59a23
7 changes: 6 additions & 1 deletion src/embed_tests/Codecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,13 +421,18 @@ public PyObject TryEncode(object value)
}
}

class InstancelessExceptionDecoder : IPyObjectDecoder
class InstancelessExceptionDecoder : IPyObjectDecoder, IDisposable
{
readonly PyObject PyErr = Py.Import("clr.interop").GetAttr("PyErr");

public bool CanDecode(PyType objectType, Type targetType)
=> PythonReferenceComparer.Instance.Equals(PyErr, objectType);

public void Dispose()
{
PyErr.Dispose();
}

public bool TryDecode<T>(PyObject pyObj, out T value)
{
if (pyObj.HasAttr("value"))
Expand Down
1 change: 1 addition & 0 deletions src/embed_tests/Inheritance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public void SetUp()
[OneTimeTearDown]
public void Dispose()
{
ExtraBaseTypeProvider.ExtraBase.Dispose();
PythonEngine.Shutdown();
}

Expand Down
2 changes: 2 additions & 0 deletions src/embed_tests/pyinitialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ public static void TestRunExitFuncs()
{
Assert.Fail(msg);
}
PythonEngine.InteropConfiguration = InteropConfiguration.MakeDefault();
return;
}
bool called = false;
Expand All @@ -187,6 +188,7 @@ public static void TestRunExitFuncs()
atexit.Dispose();
Runtime.Runtime.Shutdown();
Assert.True(called);
PythonEngine.InteropConfiguration = InteropConfiguration.MakeDefault();
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/runtime/Codecs/DecoderGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Python.Runtime.Codecs
/// <summary>
/// Represents a group of <see cref="IPyObjectDecoder"/>s. Useful to group them by priority.
/// </summary>
public sealed class DecoderGroup: IPyObjectDecoder, IEnumerable<IPyObjectDecoder>
public sealed class DecoderGroup: IPyObjectDecoder, IEnumerable<IPyObjectDecoder>, IDisposable
{
readonly List<IPyObjectDecoder> decoders = new List<IPyObjectDecoder>();

Expand Down Expand Up @@ -46,6 +46,15 @@ public bool TryDecode<T>(PyObject pyObj, out T value)
/// <inheritdoc />
public IEnumerator<IPyObjectDecoder> GetEnumerator() => this.decoders.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => this.decoders.GetEnumerator();

public void Dispose()
{
foreach (var decoder in this.decoders.OfType<IDisposable>())
{
decoder.Dispose();
}
this.decoders.Clear();
}
}

public static class DecoderGroupExtensions
Expand Down
11 changes: 10 additions & 1 deletion src/runtime/Codecs/EncoderGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Python.Runtime.Codecs
/// <summary>
/// Represents a group of <see cref="IPyObjectDecoder"/>s. Useful to group them by priority.
/// </summary>
public sealed class EncoderGroup: IPyObjectEncoder, IEnumerable<IPyObjectEncoder>
public sealed class EncoderGroup: IPyObjectEncoder, IEnumerable<IPyObjectEncoder>, IDisposable
{
readonly List<IPyObjectEncoder> encoders = new List<IPyObjectEncoder>();

Expand Down Expand Up @@ -47,6 +47,15 @@ public PyObject TryEncode(object value)
/// <inheritdoc />
public IEnumerator<IPyObjectEncoder> GetEnumerator() => this.encoders.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => this.encoders.GetEnumerator();

public void Dispose()
{
foreach (var encoder in this.encoders.OfType<IDisposable>())
{
encoder.Dispose();
}
this.encoders.Clear();
}
}

public static class EncoderGroupExtensions
Expand Down
12 changes: 11 additions & 1 deletion src/runtime/InteropConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ namespace Python.Runtime
{
using System;
using System.Collections.Generic;
using System.Linq;

using Python.Runtime.Mixins;

public sealed class InteropConfiguration
public sealed class InteropConfiguration: IDisposable
{
internal readonly PythonBaseTypeProviderGroup pythonBaseTypeProviders
= new PythonBaseTypeProviderGroup();
Expand All @@ -24,5 +25,14 @@ public static InteropConfiguration MakeDefault()
},
};
}

public void Dispose()
{
foreach (var provider in PythonBaseTypeProviders.OfType<IDisposable>())
{
provider.Dispose();
}
PythonBaseTypeProviders.Clear();
}
}
}
10 changes: 9 additions & 1 deletion src/runtime/Mixins/CollectionMixinsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Python.Runtime.Mixins
{
class CollectionMixinsProvider : IPythonBaseTypeProvider
class CollectionMixinsProvider : IPythonBaseTypeProvider, IDisposable
{
readonly Lazy<PyObject> mixinsModule;
public CollectionMixinsProvider(Lazy<PyObject> mixinsModule)
Expand Down Expand Up @@ -86,5 +86,13 @@ static Type[] NewInterfaces(Type type)

static Type GetDefinition(Type type)
=> type.IsGenericType ? type.GetGenericTypeDefinition() : type;

public void Dispose()
{
if (this.mixinsModule.IsValueCreated)
{
this.mixinsModule.Value.Dispose();
}
}
}
}
4 changes: 2 additions & 2 deletions src/runtime/converterextensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ internal static void Reset()
{
clrToPython.Clear();
pythonToClr.Clear();
encoders.Clear();
decoders.Clear();
encoders.Dispose();
decoders.Dispose();
}
}

Expand Down
1 change: 0 additions & 1 deletion src/runtime/pythonengine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,6 @@ public static void Shutdown(ShutdownMode mode)
ExecuteShutdownHandlers();
// Remember to shut down the runtime.
Runtime.Shutdown(mode);
PyObjectConversions.Reset();

initialized = false;

Expand Down
13 changes: 13 additions & 0 deletions src/runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ internal static void Shutdown(ShutdownMode mode)
PyCLRMetaType = IntPtr.Zero;

Exceptions.Shutdown();
PythonEngine.InteropConfiguration.Dispose();
DisposeLazyModule(clrInterop);
DisposeLazyModule(inspect);
PyObjectConversions.Reset();

Finalizer.Shutdown();
InternString.Shutdown();

Expand Down Expand Up @@ -424,6 +429,14 @@ internal static void Shutdown()
Shutdown(mode);
}

static void DisposeLazyModule(Lazy<PyObject> module)
{
if (module.IsValueCreated)
{
module.Value.Dispose();
}
}

private static Lazy<PyObject> GetModuleLazy(string moduleName)
=> moduleName is null
? throw new ArgumentNullException(nameof(moduleName))
Expand Down