Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
create unnamed pyscope, make PyScope.GILState save
remove method GetInstHandle
add function to create unnamed pyscope
add a field isDisposed for PyScope.GILState to make it more save
  • Loading branch information
yagweb committed Apr 7, 2017
commit b0d57e997790a889595571a2aaae36e8459d5311
80 changes: 48 additions & 32 deletions src/runtime/pythonengine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,15 @@ public class PyScope : IDisposable
public class GILState : IDisposable
{
private bool isGetGIL;

private bool isDisposed;

private IntPtr state;

internal GILState()
{
isGetGIL = false;
isDisposed = false;
}

public void AcquireLock()
Expand All @@ -563,6 +568,12 @@ public void ReleaseLock()

public void Dispose()
{
if (isDisposed)
{
return;
}
isDisposed = true;
AcquireLock();
ReleaseLock();
GC.SuppressFinalize(this);
}
Expand All @@ -573,9 +584,17 @@ public void Dispose()
}
}

private string name;
public string Name
{
get;
private set;
}

private PyScope parent;
public PyScope Parent
{
get;
private set;
}

private GILState state;

Expand All @@ -601,7 +620,7 @@ internal PyScope(string name, GILState state)
: this(state)
{
this.state = state;
this.name = name;
this.Name = name;
Runtime.PyDict_SetItemString(
globals, "__builtins__",
Runtime.PyEval_GetBuiltins()
Expand All @@ -612,7 +631,7 @@ internal PyScope(PyScope parent, GILState state)
: this(state)
{
this.state = state;
this.parent = parent;
this.Parent = parent;
globals = Runtime.PyDict_New();
if (globals == IntPtr.Zero)
{
Expand Down Expand Up @@ -792,7 +811,7 @@ internal void SetGlobalVariable(string name, object value)
AcquireLock();
using (var pyKey = new PyString(name))
{
IntPtr _value = GetInstHandle(value);
IntPtr _value = Converter.ToPython(value, value?.GetType());
int r = Runtime.PyObject_SetItem(globals, pyKey.obj, _value);
if (r < 0)
{
Expand Down Expand Up @@ -833,7 +852,7 @@ public void SetVariable(string name, object value)
AcquireLock();
using (var pyKey = new PyString(name))
{
IntPtr _value = GetInstHandle(value);
IntPtr _value = Converter.ToPython(value, value?.GetType());
int r = Runtime.PyObject_SetItem(locals, pyKey.obj, _value);
if (r < 0)
{
Expand Down Expand Up @@ -919,21 +938,7 @@ public T GetVariable<T>(string name)
PyObject obj = GetVariable(name);
return (T)obj.AsManagedObject(typeof(T));
}

private static IntPtr GetInstHandle(object value)
{
if (value == null)
{
Runtime.XIncref(Runtime.PyNone);
return Runtime.PyNone;
}
else
{
IntPtr ptr = Converter.ToPython(value, value.GetType());
return ptr;
}
}


private void AcquireLock()
{
if (isDisposed)
Expand All @@ -949,12 +954,10 @@ public virtual void Dispose()
{
return;
}
AcquireLock();
Runtime.XDecref(globals);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gc issue is most likely here. You'll need to check that the engine is initialize and that it isn't finalizing before running these.

Runtime.XDecref(locals);
if (parent == null)
{
Py.RemoveSession(name);
}
Py.RemoveSession(this);
isDisposed = true;
}

Expand All @@ -978,30 +981,43 @@ public static GILState GIL()

private static PyScope.GILState gil = new PyScope.GILState();

private static List<PyScope> Sessions = new List<PyScope>();

/// <summary>
/// Sessions should be cleared after shut down.
/// Currently, the seperation of static methods into Py and PythonEngine makes the code ugly.
/// </summary>
private static Dictionary<string, PyScope> Sessions = new Dictionary<string, PyScope>();
private static Dictionary<string, PyScope> NamedSessions = new Dictionary<string, PyScope>();

public static PyScope Session(string name)
public static PyScope Session(string name = null)
{
if (!PythonEngine.IsInitialized)
{
PythonEngine.Initialize();
}
if (Sessions.ContainsKey(name))
if (name != null && NamedSessions.ContainsKey(name))
{
return Sessions[name];
return NamedSessions[name];
}
var session = new PyScope(name, gil);
Sessions[name] = session;
if(name != null)
{
NamedSessions[name] = session;
}
Sessions.Add(session);
return session;
}

internal static void RemoveSession(string name)
internal static void RemoveSession(PyScope scope)
{
Sessions.Remove(name);
if(scope.Parent == null)//top session
{
Sessions.Remove(scope);
if(scope.Name != null)
{
NamedSessions.Remove(scope.Name);
}
}
}

public class GILState : IDisposable
Expand Down