@@ -21,9 +21,11 @@ public PythonException()
2121 _referenceDecrementer = PythonEngine . CurrentRefDecrementer ;
2222 IntPtr gs = PythonEngine . AcquireLock ( ) ;
2323 Runtime . PyErr_Fetch ( ref _pyType , ref _pyValue , ref _pyTB ) ;
24- Runtime . XIncref ( _pyType ) ;
25- Runtime . XIncref ( _pyValue ) ;
26- Runtime . XIncref ( _pyTB ) ;
24+
25+ // Those references already owned by the caller
26+ ////Runtime.XIncref(_pyType);
27+ ////Runtime.XIncref(_pyValue);
28+ ////Runtime.XIncref(_pyTB);
2729 if ( _pyType != IntPtr . Zero && _pyValue != IntPtr . Zero )
2830 {
2931 string type ;
@@ -44,7 +46,13 @@ public PythonException()
4446 }
4547 if ( _pyTB != IntPtr . Zero )
4648 {
47- PyObject tb_module = PythonEngine . ImportModule ( "traceback" ) ;
49+
50+ if ( _tbModule == null )
51+ {
52+ _tbModule = PythonEngine . ImportModule ( "traceback" ) ;
53+ }
54+ PyObject tb_module = _tbModule ;
55+
4856 Runtime . XIncref ( _pyTB ) ;
4957 using ( var pyTB = new PyObject ( _pyTB ) )
5058 {
@@ -54,11 +62,14 @@ public PythonException()
5462 PythonEngine . ReleaseLock ( gs ) ;
5563 }
5664
65+ private static PyObject _tbModule ;
66+
5767 // Ensure that encapsulated Python objects are decref'ed appropriately
5868 // when the managed exception wrapper is garbage-collected.
5969
6070 ~ PythonException ( )
6171 {
72+
6273 Dispose ( false ) ;
6374 }
6475
@@ -152,49 +163,51 @@ protected void Dispose(bool disposing)
152163 {
153164 disposed = true ;
154165
166+ IntPtr pyTypeToDispose = _pyType ;
167+ _pyType = IntPtr . Zero ;
168+
169+ IntPtr pyValueToDispose = _pyValue ;
170+ _pyValue = IntPtr . Zero ;
171+
172+ IntPtr pyTBToDispose = _pyTB ;
173+ _pyTB = IntPtr . Zero ;
174+
155175 if ( disposing )
156176 {
157177 if ( Runtime . Py_IsInitialized ( ) > 0 && ! Runtime . IsFinalizing )
158178 {
179+ IntPtr gs = PythonEngine . AcquireLock ( ) ;
159180 try
160181 {
161- IntPtr gs = PythonEngine . AcquireLock ( ) ;
162- try
163- {
164- Runtime . XDecref ( _pyType ) ;
165- Runtime . XDecref ( _pyValue ) ;
166- // XXX Do we ever get TraceBack? //
167- if ( _pyTB != IntPtr . Zero )
168- {
169- Runtime . XDecref ( _pyTB ) ;
170- }
171- }
172- finally
182+ Runtime . XDecref ( pyTypeToDispose ) ;
183+ Runtime . XDecref ( pyValueToDispose ) ;
184+ // XXX Do we ever get TraceBack? //
185+ if ( pyTBToDispose != IntPtr . Zero )
173186 {
174- PythonEngine . ReleaseLock ( gs ) ;
187+ Runtime . XDecref ( pyTBToDispose ) ;
175188 }
176189 }
177- catch
190+ finally
178191 {
179- // Do nothing.
192+ PythonEngine . ReleaseLock ( gs ) ;
180193 }
181194 }
182195 }
183196 else
184197 {
185- if ( _pyType != IntPtr . Zero )
198+ if ( pyTypeToDispose != IntPtr . Zero )
186199 {
187- _referenceDecrementer ? . ScheduleDecRef ( _pyType ) ;
200+ _referenceDecrementer ? . ScheduleDecRef ( pyTypeToDispose ) ;
188201 }
189202
190- if ( _pyValue != IntPtr . Zero )
203+ if ( pyValueToDispose != IntPtr . Zero )
191204 {
192- _referenceDecrementer ? . ScheduleDecRef ( _pyValue ) ;
205+ _referenceDecrementer ? . ScheduleDecRef ( pyValueToDispose ) ;
193206 }
194207
195- if ( _pyTB != IntPtr . Zero )
208+ if ( pyTBToDispose != IntPtr . Zero )
196209 {
197- _referenceDecrementer ? . ScheduleDecRef ( _pyTB ) ;
210+ _referenceDecrementer ? . ScheduleDecRef ( pyTBToDispose ) ;
198211 }
199212 }
200213 }
0 commit comments