|
1 | 1 | using System;
|
2 | 2 | using System.Collections.Generic;
|
| 3 | +using System.Diagnostics; |
3 | 4 | using System.Linq;
|
4 | 5 | using System.Runtime.InteropServices;
|
5 | 6 | using System.Text;
|
@@ -214,8 +215,45 @@ public int Read(byte[] buffer, int offset, int count) {
|
214 | 215 |
|
215 | 216 | private void Dispose(bool disposing)
|
216 | 217 | {
|
217 |
| - if (!disposedValue) { |
218 |
| - Runtime.PyBuffer_Release(ref _view); |
| 218 | + if (!disposedValue
8000
) |
| 219 | + { |
| 220 | + Debug.Assert(_view.obj != IntPtr.Zero, "Buffer object is invalid (no exporter object ref)"); |
| 221 | + //if (_view.obj == IntPtr.Zero) |
| 222 | + //{ |
| 223 | + // return; |
| 224 | + //} |
| 225 | + |
| 226 | + if (Runtime.Py_IsInitialized() == 0) |
| 227 | + throw new InvalidOperationException("Python runtime must be initialized"); |
| 228 | + |
| 229 | + if (!Runtime.IsFinalizing) |
| 230 | + { |
| 231 | + long refcount = Runtime.Refcount(_view.obj); |
| 232 | + Debug.Assert(refcount > 0, "Object refcount is 0 or less"); |
| 233 | + |
| 234 | + if (refcount == 1) |
| 235 | + { |
| 236 | + Runtime.PyErr_Fetch(out var errType, out var errVal, out var traceback); |
| 237 | + |
| 238 | + try |
| 239 | + { |
| 240 | + // this also decrements ref count for _view->obj |
| 241 | + Runtime.PyBuffer_Release(ref _view); |
| 242 | + Runtime.CheckExceptionOccurred(); |
| 243 | + } |
| 244 | + finally |
| 245 | + { |
| 246 | + // Python requires finalizers to preserve exception: |
| 247 | + // https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation |
| 248 | + Runtime.PyErr_Restore(errType, errVal, traceback); |
| 249 | + } |
| 250 | + } |
| 251 | + else |
| 252 | + { |
| 253 | + // this also decrements ref count for _view->obj |
| 254 | + Runtime.PyBuffer_Release(ref _view); |
| 255 | + } |
| 256 | + } |
219 | 257 |
|
220 | 258 | _exporter = null;
|
221 | 259 | Shape = null;
|
|
0 commit comments