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

Skip to content

Commit b0d57e9

Browse files
committed
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
1 parent c15555c commit b0d57e9

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

src/runtime/pythonengine.cs

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,15 @@ public class PyScope : IDisposable
536536
public class GILState : IDisposable
537537
{
538538
private bool isGetGIL;
539+
540+
private bool isDisposed;
541+
539542
private IntPtr state;
540543

541544
internal GILState()
542545
{
546+
isGetGIL = false;
547+
isDisposed = false;
543548
}
544549

545550
public void AcquireLock()
@@ -563,6 +568,12 @@ public void ReleaseLock()
563568

564569
public void Dispose()
565570
{
571+
if (isDisposed)
572+
{
573+
return;
574+
}
575+
isDisposed = true;
576+
AcquireLock();
566577
ReleaseLock();
567578
GC.SuppressFinalize(this);
568579
}
@@ -573,9 +584,17 @@ public void Dispose()
573584
}
574585
}
575586

576-
private string name;
587+
public string Name
588+
{
589+
get;
590+
private set;
591+
}
577592

578-
private PyScope parent;
593+
public PyScope Parent
594+
{
595+
get;
596+
private set;
597+
}
579598

580599
private GILState state;
581600

@@ -601,7 +620,7 @@ internal PyScope(string name, GILState state)
601620
: this(state)
602621
{
603622
this.state = state;
604-
this.name = name;
623+
this.Name = name;
605624
Runtime.PyDict_SetItemString(
606625
globals, "__builtins__",
607626
Runtime.PyEval_GetBuiltins()
@@ -612,7 +631,7 @@ internal PyScope(PyScope parent, GILState state)
612631
: this(state)
613632
{
614633
this.state = state;
615-
this.parent = parent;
634+
this.Parent = parent;
616635
globals = Runtime.PyDict_New();
617636
if (globals == IntPtr.Zero)
618637
{
@@ -792,7 +811,7 @@ internal void SetGlobalVariable(string name, object value)
792811
AcquireLock();
793812
using (var pyKey = new PyString(name))
794813
{
795-
IntPtr _value = GetInstHandle(value);
814+
IntPtr _value = Converter.ToPython(value, value?.GetType());
796815
int r = Runtime.PyObject_SetItem(globals, pyKey.obj, _value);
797816
if (r < 0)
798817
{
@@ -833,7 +852,7 @@ public void SetVariable(string name, object value)
833852
AcquireLock();
834853
using (var pyKey = new PyString(name))
835854
{
836-
IntPtr _value = GetInstHandle(value);
855+
IntPtr _value = Converter.ToPython(value, value?.GetType());
837856
int r = Runtime.PyObject_SetItem(locals, pyKey.obj, _value);
838857
if (r < 0)
839858
{
@@ -919,21 +938,7 @@ public T GetVariable<T>(string name)
919938
PyObject obj = GetVariable(name);
920939
return (T)obj.AsManagedObject(typeof(T));
921940
}
922-
923-
private static IntPtr GetInstHandle(object value)
924-
{
925-
if (value == null)
926-
{
927-
Runtime.XIncref(Runtime.PyNone);
928-
return Runtime.PyNone;
929-
}
930-
else
931-
{
932-
IntPtr ptr = Converter.ToPython(value, value.GetType());
933-
return ptr;
934-
}
935-
}
936-
941+
937942
private void AcquireLock()
938943
{
939944
if (isDisposed)
@@ -949,12 +954,10 @@ public virtual void Dispose()
949954
{
950955
return;
951956
}
957+
AcquireLock();
952958
Runtime.XDecref(globals);
953959
Runtime.XDecref(locals);
954-
if (parent == null)
955-
{
956-
Py.RemoveSession(name);
957-
}
960+
Py.RemoveSession(this);
958961
isDisposed = true;
959962
}
960963

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

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

984+
private static List<PyScope> Sessions = new List<PyScope>();
985+
981986
/// <summary>
982987
/// Sessions should be cleared after shut down.
983988
/// Currently, the seperation of static methods into Py and PythonEngine makes the code ugly.
984989
/// </summary>
985-
private static Dictionary<string, PyScope> Sessions = new Dictionary<string, PyScope>();
990+
private static Dictionary<string, PyScope> NamedSessions = new Dictionary<string, PyScope>();
986991

987-
public static PyScope Session(string name)
992+
public static PyScope Session(string name = null)
988993
{
989994
if (!PythonEngine.IsInitialized)
990995
{
991996
PythonEngine.Initialize();
992997
}
993-
if (Sessions.ContainsKey(name))
998+
if (name != null && NamedSessions.ContainsKey(name))
994999
{
995-
return Sessions[name];
1000+
return NamedSessions[name];
9961001
}
9971002
var session = new PyScope(name, gil);
998-
Sessions[name] = session;
1003+
if(name != null)
1004+
{
1005+
NamedSessions[name] = session;
1006+
}
1007+
Sessions.Add(session);
9991008
return session;
10001009
}
10011010

1002-
internal static void RemoveSession(string name)
1011+
internal static void RemoveSession(PyScope scope)
10031012
{
1004-
Sessions.Remove(name);
1013+
if(scope.Parent == null)//top session
1014+
{
1015+
Sessions.Remove(scope);
1016+
if(scope.Name != null)
1017+
{
1018+
NamedSessions.Remove(scope.Name);
1019+
}
1020+
}
10051021
}
10061022

10071023
public class GILState : IDisposable

0 commit comments

Comments
 (0)