@@ -536,10 +536,15 @@ public class PyScope : IDisposable
536
536
public class GILState : IDisposable
537
537
{
538
538
private bool isGetGIL ;
539
+
540
+ private bool isDisposed ;
541
+
539
542
private IntPtr state ;
540
543
541
544
internal GILState ( )
542
545
{
546
+ isGetGIL = false ;
547
+ isDisposed = false ;
543
548
}
544
549
545
550
public void AcquireLock ( )
@@ -563,6 +568,12 @@ public void ReleaseLock()
563
568
564
569
public void Dispose ( )
565
570
{
571
+ if ( isDisposed )
572
+ {
573
+ return ;
574
+ }
575
+ isDisposed = true ;
576
+ AcquireLock ( ) ;
566
577
ReleaseLock ( ) ;
567
578
GC . SuppressFinalize ( this ) ;
568
579
}
@@ -573,9 +584,17 @@ public void Dispose()
573
584
}
574
585
}
575
586
576
- private string name ;
587
+ public string Name
588
+ {
589
+ get ;
590
+ private set ;
591
+ }
577
592
578
- private PyScope parent ;
593
+ public PyScope Parent
594
+ {
595
+ get ;
596
+ private set ;
597
+ }
579
598
580
599
private GILState state ;
581
600
@@ -601,7 +620,7 @@ internal PyScope(string name, GILState state)
601
620
: this ( state )
602
621
{
603
622
this . state = state ;
604
- this . name = name ;
623
+ this . Name = name ;
605
624
Runtime . PyDict_SetItemString (
606
625
globals , "__builtins__" ,
607
626
Runtime . PyEval_GetBuiltins ( )
@@ -612,7 +631,7 @@ internal PyScope(PyScope parent, GILState state)
612
631
: this ( state )
613
632
{
614
633
this . state = state ;
615
- this . parent = parent ;
634
+ this . Parent = parent ;
616
635
globals = Runtime . PyDict_New ( ) ;
617
636
if ( globals == IntPtr . Zero )
618
637
{
@@ -792,7 +811,7 @@ internal void SetGlobalVariable(string name, object value)
792
811
AcquireLock ( ) ;
793
812
using ( var pyKey = new PyString ( name ) )
794
813
{
795
- IntPtr _value = GetInstHandle ( value ) ;
814
+ IntPtr _value = Converter . ToPython ( value , value ? . GetType ( ) ) ;
796
815
int r = Runtime . PyObject_SetItem ( globals , pyKey . obj , _value ) ;
797
816
if ( r < 0 )
798
817
{
@@ -833,7 +852,7 @@ public void SetVariable(string name, object value)
833
852
AcquireLock ( ) ;
834
853
using ( var pyKey = new PyString ( name ) )
835
854
{
836
- IntPtr _value = GetInstHandle ( value ) ;
855
+ IntPtr _value = Converter . ToPython ( value , value ? . GetType ( ) ) ;
837
856
int r = Runtime . PyObject_SetItem ( locals , pyKey . obj , _value ) ;
838
857
if ( r < 0 )
839
858
{
@@ -919,21 +938,7 @@ public T GetVariable<T>(string name)
919
938
PyObject obj = GetVariable ( name ) ;
920
939
return ( T ) obj . AsManagedObject ( typeof ( T ) ) ;
921
940
}
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
+
937
942
private void AcquireLock ( )
938
943
{
939
944
if ( isDisposed )
@@ -949,12 +954,10 @@ public virtual void Dispose()
949
954
{
950
955
return ;
951
956
}
957
+ AcquireLock ( ) ;
952
958
Runtime . XDecref ( globals ) ;
953
959
Runtime . XDecref ( locals ) ;
954
- if ( parent == null )
955
- {
956
- Py . RemoveSession ( name ) ;
957
- }
960
+ Py . RemoveSession ( this ) ;
958
961
isDisposed = true ;
959
962
}
960
963
@@ -978,30 +981,43 @@ public static GILState GIL()
978
981
979
982
private static PyScope . GILState gil = new PyScope . GILState ( ) ;
980
983
984
+ private static List < PyScope > Sessions = new List < PyScope > ( ) ;
985
+
981
986
/// <summary>
982
987
/// Sessions should be cleared after shut down.
983
988
/// Currently, the seperation of static methods into Py and PythonEngine makes the code ugly.
984
989
/// </summary>
985
- private static Dictionary < string , PyScope > Sessions = new Dictionary < string , PyScope > ( ) ;
990
+ private static Dictionary < string , PyScope > NamedSessions = new Dictionary < string , PyScope > ( ) ;
986
991
987
- public static PyScope Session ( string name )
992
+ public static PyScope Session ( string name = null )
988
993
{
989
994
if ( ! PythonEngine . IsInitialized )
990
995
{
991
996
PythonEngine . Initialize ( ) ;
992
997
}
993
- if ( Sessions . ContainsKey ( name ) )
998
+ if ( name != null && NamedSessions . ContainsKey ( name ) )
994
999
{
995
- return Sessions [ name ] ;
1000
+ return NamedSessions [ name ] ;
996
1001
}
997
1002
var session = new PyScope ( name , gil ) ;
998
- Sessions [ name ] = session ;
1003
+ if ( name != null )
1004
+ {
1005
+ NamedSessions [ name ] = session ;
1006
+ }
1007
+ Sessions . Add ( session ) ;
999
1008
return session ;
1000
1009
}
1001
1010
1002
- internal static void RemoveSession ( string name )
1011
+ internal static void RemoveSession ( PyScope scope )
1003
1012
{
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
+ }
1005
1021
}
1006
1022
1007
1023
public class GILState : IDisposable
0 commit comments