@@ -198,71 +198,91 @@ internal static void Initialize(bool initSigs = false)
198198 IntPtr op ;
199199 {
200200 var builtins = GetBuiltins ( ) ;
201- SetPyMember ( ref PyNotImplemented , PyObject_GetAttrString ( builtins , "NotImplemented" ) ) ;
202-
203- SetPyMember ( ref PyBaseObjectType , PyObject_GetAttrString ( builtins , "object" ) ) ;
204-
205- SetPyMember ( ref PyNone , PyObject_GetAttrString ( builtins , "None" ) ) ;
206- SetPyMember ( ref PyTrue , PyObject_GetAttrString ( builtins , "True" ) ) ;
207- SetPyMember ( ref PyFalse , PyObject_GetAttrString ( builtins , "False" ) ) ;
208-
209- SetPyMember ( ref PyBoolType , PyObject_Type ( PyTrue ) ) ;
210- SetPyMember ( ref PyNoneType , PyObject_Type ( PyNone ) ) ;
211- SetPyMember ( ref PyTypeType , PyObject_Type ( PyNoneType ) ) ;
201+ SetPyMember ( ref PyNotImplemented , PyObject_GetAttrString ( builtins , "NotImplemented" ) ,
202+ ( ) => PyNotImplemented = IntPtr . Zero ) ;
203+
204+ SetPyMember ( ref PyBaseObjectType , PyObject_GetAttrString ( builtins , "object" ) ,
205+ ( ) => PyBaseObjectType = IntPtr . Zero ) ;
206+
207+ SetPyMember ( ref PyNone , PyObject_GetAttrString ( builtins , "None" ) ,
208+ ( ) => PyNone = IntPtr . Zero ) ;
209+ SetPyMember ( ref PyTrue , PyObject_GetAttrString ( builtins , "True" ) ,
210+ ( ) => PyTrue = IntPtr . Zero ) ;
211+ SetPyMember ( ref PyFalse , PyObject_GetAttrString ( builtins , "False" ) ,
212+ ( ) => PyFalse = IntPtr . Zero ) ;
213+
214+ SetPyMember ( ref PyBoolType , PyObject_Type ( PyTrue ) ,
215+ ( ) => PyBoolType = IntPtr . Zero ) ;
216+ SetPyMember ( ref PyNoneType , PyObject_Type ( PyNone ) ,
217+ ( ) => PyNoneType = IntPtr . Zero ) ;
218+ SetPyMember ( ref PyTypeType , PyObject_Type ( PyNoneType ) ,
219+ ( ) => PyTypeType = IntPtr . Zero ) ;
212220
213221 op = PyObject_GetAttrString ( builtins , "len" ) ;
214- SetPyMember ( ref PyMethodType , PyObject_Type ( op ) ) ;
222+ SetPyMember ( ref PyMethodType , PyObject_Type ( op ) ,
223+ ( ) => PyMethodType = IntPtr . Zero ) ;
215224 XDecref ( op ) ;
216225
217226 // For some arcane reason, builtins.__dict__.__setitem__ is *not*
218227 // a wrapper_descriptor, even though dict.__setitem__ is.
219228 //
220229 // object.__init__ seems safe, though.
221230 op = PyObject_GetAttrString ( PyBaseObjectType , "__init__" ) ;
222- SetPyMember ( ref PyWrapperDescriptorType , PyObject_Type ( op ) ) ;
231+ SetPyMember ( ref PyWrapperDescriptorType , PyObject_Type ( op ) ,
232+ ( ) => PyWrapperDescriptorType = IntPtr . Zero ) ;
223233 XDecref ( op ) ;
224234
225- SetPyMember ( ref PySuper_Type , PyObject_GetAttrString ( builtins , "super" ) ) ;
235+ SetPyMember ( ref PySuper_Type , PyObject_GetAttrString ( builtins , "super" ) ,
236+ ( ) => PySuper_Type = IntPtr . Zero ) ;
226237
227238 XDecref ( builtins ) ;
228239 }
229240
230241 op = PyString_FromString ( "string" ) ;
231- SetPyMember ( ref PyStringType , PyObject_Type ( op ) ) ;
242+ SetPyMember ( ref PyStringType , PyObject_Type ( op ) ,
243+ ( ) => PyStringType = IntPtr . Zero ) ;
232244 XDecref ( op ) ;
233245
234246 op = PyUnicode_FromString ( "unicode" ) ;
235- SetPyMember ( ref PyUnicodeType , PyObject_Type ( op ) ) ;
247+ SetPyMember ( ref PyUnicodeType , PyObject_Type ( op ) ,
248+ ( ) => PyUnicodeType = IntPtr . Zero ) ;
236249 XDecref ( op ) ;
237250
238251#if PYTHON3
239252 op = PyBytes_FromString ( "bytes" ) ;
240- SetPyMember ( ref PyBytesType , PyObject_Type ( op ) ) ;
253+ SetPyMember ( ref PyBytesType , PyObject_Type ( op ) ,
254+ ( ) => PyBytesType = IntPtr . Zero ) ;
241255 XDecref ( op ) ;
242256#endif
243257
244258 op = PyTuple_New ( 0 ) ;
245- SetPyMember ( ref PyTupleType , PyObject_Type ( op ) ) ;
259+ SetPyMember ( ref PyTupleType , PyObject_Type ( op ) ,
260+ ( ) => PyTupleType = IntPtr . Zero ) ;
246261 XDecref ( op ) ;
247262
248263 op = PyList_New ( 0 ) ;
249- SetPyMember ( ref PyListType , PyObject_Type ( op ) ) ;
264+ SetPyMember ( ref PyListType , PyObject_Type ( op ) ,
265+ ( ) => PyListType = IntPtr . Zero ) ;
250266 XDecref ( op ) ;
251267
252268 op = PyDict_New ( ) ;
253- SetPyMember ( ref PyDictType , PyObject_Type ( op ) ) ;
269+ SetPyMember ( ref PyDictType , PyObject_Type ( op ) ,
270+ ( ) => PyDictType = IntPtr . Zero ) ;
254271 XDecref ( op ) ;
255272
256273 op = PyInt_FromInt32 ( 0 ) ;
257- SetPyMember ( ref PyIntType , PyObject_Type ( op ) ) ;
274+ SetPyMember ( ref PyIntType , PyObject_Type ( op ) ,
275+ ( ) => PyIntType = IntPtr . Zero ) ;
258276 XDecref ( op ) ;
259277
260278 op = PyLong_FromLong ( 0 ) ;
261- SetPyMember ( ref PyLongType , PyObject_Type ( op ) ) ;
279+ SetPyMember ( ref PyLongType , PyObject_Type ( op ) ,
280+ ( ) => PyLongType = IntPtr . Zero ) ;
262281 XDecref ( op ) ;
263282
264283 op = PyFloat_FromDouble ( 0 ) ;
265- SetPyMember ( ref PyFloatType , PyObject_Type ( op ) ) ;
284+ SetPyMember ( ref PyFloatType , PyObject_Type ( op ) ,
285+ ( ) => PyFloatType = IntPtr . Zero ) ;
266286 XDecref ( op ) ;
267287
268288#if ! PYTHON2
@@ -274,10 +294,12 @@ internal static void Initialize(bool initSigs = false)
274294 IntPtr d = PyDict_New ( ) ;
275295
276296 IntPtr c = PyClass_New ( IntPtr . Zero , d , s ) ;
277- SetPyMember ( ref PyClassType , PyObject_Type ( c ) ) ;
297+ SetPyMember ( ref PyClassType , PyObject_Type ( c ) ,
298+ ( ) => PyClassType = IntPtr . Zero ) ;
278299
279300 IntPtr i = PyInstance_New ( c , IntPtr . Zero , IntPtr . Zero ) ;
280- SetPyMember ( ref PyInstanceType , PyObject_Type ( i ) ) ;
301+ SetPyMember ( ref PyInstanceType , PyObject_Type ( i ) ,
302+ ( ) => PyInstanceType = IntPtr . Zero ) ;
281303
282304 XDecref ( s ) ;
283305 XDecref ( i ) ;
@@ -393,12 +415,12 @@ internal static int AtExit()
393415 return 0 ;
394416 }
395417
396- private static void SetPyMember ( ref IntPtr obj , IntPtr value )
418+ private static void SetPyMember ( ref IntPtr obj , IntPtr value , Action onRelease )
397419 {
398420 // XXX: For current usages, value should not be null.
399421 PythonException . ThrowIfIsNull ( value ) ;
400422 obj = value ;
401- _pyRefs . Add ( ref obj ) ;
423+ _pyRefs . Add ( value , onRelease ) ;
402424 }
403425
404426 private static void ResetPyMembers ( )
@@ -977,7 +999,7 @@ internal static int PyObject_Compare(IntPtr value1, IntPtr value2)
977999
9781000 internal static long PyObject_Size( IntPtr pointer)
9791001 {
980- return ( long ) _PyObject_Size( pointer) ;
1002+ return ( long ) _PyObject_Size( pointer) ;
9811003 }
9821004
9831005 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyObject_Size") ]
@@ -1093,7 +1115,7 @@ internal static bool PyLong_Check(IntPtr ob)
10931115
10941116 internal static IntPtr PyLong_FromUnsignedLong( object value)
10951117 {
1096- if ( Is32Bit || IsWindows)
1118+ if ( Is32Bit || IsWindows)
10971119 return PyLong_FromUnsignedLong32( Convert. ToUInt32( value) ) ;
10981120 else
10991121 return PyLong_FromUnsignedLong64( Convert. ToUInt64( value) ) ;
@@ -1283,7 +1305,7 @@ internal static int PySequence_DelSlice(IntPtr pointer, long i1, long i2)
12831305
12841306 internal static long PySequence_Size( IntPtr pointer)
12851307 {
1286- return ( long ) _PySequence_Size( pointer) ;
1308+ return ( long ) _PySequence_Size( pointer) ;
12871309 }
12881310
12891311 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PySequence_Size") ]
@@ -1308,7 +1330,7 @@ internal static IntPtr PySequence_Repeat(IntPtr pointer, long count)
13081330
13091331 internal static long PySequence_Count( IntPtr pointer, IntPtr value)
13101332 {
1311- return ( long ) _PySequence_Count( pointer, value) ;
1333+ return ( long ) _PySequence_Count( pointer, value) ;
13121334 }
13131335
13141336 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PySequence_Count") ]
@@ -1351,7 +1373,7 @@ internal static IntPtr PyString_FromString(string value)
13511373
13521374 internal static long PyBytes_Size( IntPtr op)
13531375 {
1354- return ( long ) _PyBytes_Size( op) ;
1376+ return ( long ) _PyBytes_Size( op) ;
13551377 }
13561378
13571379 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyBytes_Size") ]
@@ -1582,7 +1604,7 @@ internal static bool PyDict_Check(IntPtr ob)
15821604
15831605 internal static long PyDict_Size( IntPtr pointer)
15841606 {
1585- return ( long ) _PyDict_Size( pointer) ;
1607+ return ( long ) _PyDict_Size( pointer) ;
15861608 }
15871609
15881610 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyDict_Size") ]
@@ -1660,7 +1682,7 @@ internal static int PyList_SetSlice(IntPtr pointer, long start, long end, IntPtr
16601682
16611683 internal static long PyList_Size( IntPtr pointer)
16621684 {
1663- return ( long ) _PyList_Size( pointer) ;
1685+ return ( long ) _PyList_Size( pointer) ;
16641686 }
16651687
16661688 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyList_Size") ]
@@ -1709,7 +1731,7 @@ internal static IntPtr PyTuple_GetSlice(IntPtr pointer, long start, long end)
17091731
17101732 internal static long PyTuple_Size( IntPtr pointer)
17111733 {
1712- return ( long ) _PyTuple_Size( pointer) ;
1734+ return ( long ) _PyTuple_Size( pointer) ;
17131735 }
17141736
17151737 [ DllImport( _PythonDll, CallingConvention = CallingConvention. Cdecl, EntryPoint = "PyTuple_Size") ]
@@ -1976,40 +1998,25 @@ internal static IntPtr GetBuiltins()
19761998
19771999 class PyReferenceCollection
19782000 {
1979- public List< IntPtr> _objects { get ; private set ; }
1980-
1981- public PyReferenceCollection( )
1982- {
1983- _objects = new List< IntPtr> ( ) ;
1984- }
2001+ private List< KeyValuePair< IntPtr, Action>> _actions = new List< KeyValuePair< IntPtr, Action>> ( ) ;
19852002
19862003 /// <summary>
19872004 /// Record obj's address to release the obj in the future,
19882005 /// obj must alive before calling Release.
19892006 /// </summary>
1990- public void Add( ref IntPtr obj )
2007+ public void Add( IntPtr ob , Action onRelease )
19912008 {
1992- unsafe
1993- {
1994- fixed ( void * p = & obj)
1995- {
1996- _objects. Add( ( IntPtr) p) ;
1997- }
1998- }
2009+ _actions. Add( new KeyValuePair< IntPtr, Action> ( ob, onRelease) ) ;
19992010 }
20002011
20012012 public void Release( )
20022013 {
2003- foreach ( var objRef in _objects )
2014+ foreach ( var item in _actions )
20042015 {
2005- unsafe
2006- {
2007- var p = ( void * * ) objRef;
2008- Runtime. XDecref( ( IntPtr) ( * p) ) ;
2009- * p = null ;
2010- }
2016+ Runtime. XDecref( item. Key) ;
2017+ item. Value? . Invoke( ) ;
20112018 }
2012- _objects . Clear( ) ;
2019+ _actions . Clear( ) ;
20132020 }
20142021 }
20152022}
0 commit comments