| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,7 @@ | |||
| 38 | 38 | - Dmitriy Se ([@dmitriyse](https://github.com/dmitriyse)) | |
| 39 | 39 | - Félix Bourbonnais ([@BadSingleton](https://github.com/BadSingleton)) | |
| 40 | 40 | - Florian Treurniet ([@ftreurni](https://github.com/ftreurni)) | |
| 41 | + - Frank Witscher ([@Frawak](https://github.com/Frawak)) | ||
| 41 | 42 | - He-chien Tsai ([@t3476](https://github.com/t3476)) | |
| 42 | 43 | - Inna Wiesel ([@inna-w](https://github.com/inna-w)) | |
| 43 | 44 | - Ivan Cronyn ([@cronan](https://github.com/cronan)) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. | |||
| 24 | 24 | - Fixed RecursionError for reverse operators on C# operable types from python. See #2240 | |
| 25 | 25 | - Fixed crash when .NET event has no `AddMethod` | |
| 26 | 26 | - Fixed probing for assemblies in `sys.path` failing when a path in `sys.path` has invalid characters. See #2376 | |
| 27 | + - Fixed possible access violation exception on shutdown. See ([#1977][i1977]) | ||
| 27 | 28 | ||
| 28 | 29 | ## [3.0.3](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.3) - 2023-10-11 | |
| 29 | 30 | ||
@@ -971,3 +972,4 @@ This version improves performance on benchmarks significantly compared to 2.3. | |||
| 971 | 972 | [i1481]: https://github.com/pythonnet/pythonnet/issues/1481 | |
| 972 | 973 | [i1672]: https://github.com/pythonnet/pythonnet/pull/1672 | |
| 973 | 974 | [i2311]: https://github.com/pythonnet/pythonnet/issues/2311 | |
| 975 | + [i1977]: https://github.com/pythonnet/pythonnet/issues/1977 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -191,7 +191,7 @@ internal static void Shutdown() | |||
| 191 | 191 | Instance.started = false; | |
| 192 | 192 | } | |
| 193 | 193 | ||
| 194 | - internal nint DisposeAll() | ||
| 194 | + internal nint DisposeAll(bool disposeObj = true, bool disposeDerived = true, bool disposeBuffer = true) | ||
| 195 | 195 | { | |
| 196 | 196 | if (_objQueue.IsEmpty && _derivedQueue.IsEmpty && _bufferQueue.IsEmpty) | |
| 197 | 197 | return 0; | |
@@ -216,7 +216,7 @@ internal nint DisposeAll() | |||
| 216 | 216 | ||
| 217 | 217 | try | |
| 218 | 218 | { | |
| 219 | - while (!_objQueue.IsEmpty) | ||
| 219 | + if (disposeObj) while (!_objQueue.IsEmpty) | ||
| 220 | 220 | { | |
| 221 | 221 | if (!_objQueue.TryDequeue(out var obj)) | |
| 222 | 222 | continue; | |
@@ -240,7 +240,7 @@ internal nint DisposeAll() | |||
| 240 | 240 | } | |
| 241 | 241 | } | |
| 242 | 242 | ||
| 243 | - while (!_derivedQueue.IsEmpty) | ||
| 243 | + if (disposeDerived) while (!_derivedQueue.IsEmpty) | ||
| 244 | 244 | { | |
| 245 | 245 | if (!_derivedQueue.TryDequeue(out var derived)) | |
| 246 | 246 | continue; | |
@@ -258,7 +258,7 @@ internal nint DisposeAll() | |||
| 258 | 258 | collected++; | |
| 259 | 259 | } | |
| 260 | 260 | ||
| 261 | - while (!_bufferQueue.IsEmpty) | ||
| 261 | + if (disposeBuffer) while (!_bufferQueue.IsEmpty) | ||
| 262 | 262 | { | |
| 263 | 263 | if (!_bufferQueue.TryDequeue(out var buffer)) | |
| 264 | 264 | continue; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -158,6 +158,7 @@ internal static void Initialize(bool initSigs = false) | |||
| 158 | 158 | ClassManager.Reset(); | |
| 159 | 159 | ClassDerivedObject.Reset(); | |
| 160 | 160 | TypeManager.Initialize(); | |
| 161 | + CLRObject.creationBlocked = false; | ||
| 161 | 162 | _typesInitialized = true; | |
| 162 | 163 | ||
| 163 | 164 | // Initialize modules that depend on the runtime class. | |
@@ -278,6 +279,10 @@ internal static void Shutdown() | |||
| 278 | 279 | ClearClrModules(); | |
| 279 | 280 | RemoveClrRootModule(); | |
| 280 | 281 | ||
| 282 | + TryCollectingGarbage(MaxCollectRetriesOnShutdown, forceBreakLoops: true, | ||
| 283 | + obj: true, derived: false, buffer: false); | ||
| 284 | + CLRObject.creationBlocked = true; | ||
| 285 | + | ||
| 281 | 286 | NullGCHandles(ExtensionType.loadedExtensions); | |
| 282 | 287 | ClassManager.RemoveClasses(); | |
| 283 | 288 | TypeManager.RemoveTypes(); | |
@@ -295,8 +300,7 @@ internal static void Shutdown() | |||
| 295 | 300 | PyObjectConversions.Reset(); | |
| 296 | 301 | ||
| 297 | 302 | PyGC_Collect(); | |
| 298 | - bool everythingSeemsCollected = TryCollectingGarbage(MaxCollectRetriesOnShutdown, | ||
| 299 | - forceBreakLoops: true); | ||
| 303 | + bool everythingSeemsCollected = TryCollectingGarbage(MaxCollectRetriesOnShutdown); | ||
| 300 | 304 | Debug.Assert(everythingSeemsCollected); | |
| 301 | 305 | ||
| 302 | 306 | Finalizer.Shutdown(); | |
@@ -328,7 +332,8 @@ internal static void Shutdown() | |||
| 328 | 332 | ||
| 329 | 333 | const int MaxCollectRetriesOnShutdown = 20; | |
| 330 | 334 | internal static int _collected; | |
| 331 | - static bool TryCollectingGarbage(int runs, bool forceBreakLoops) | ||
| 335 | + static bool TryCollectingGarbage(int runs, bool forceBreakLoops, | ||
| 336 | + bool obj = true, bool derived = true, bool buffer = true) | ||
| 332 | 337 | { | |
| 333 | 338 | if (runs <= 0) throw new ArgumentOutOfRangeException(nameof(runs)); | |
| 334 | 339 | ||
@@ -341,7 +346,9 @@ static bool TryCollectingGarbage(int runs, bool forceBreakLoops) | |||
| 341 | 346 | GC.Collect(); | |
| 342 | 347 | GC.WaitForPendingFinalizers(); | |
| 343 | 348 | pyCollected += PyGC_Collect(); | |
| 344 | - pyCollected += Finalizer.Instance.DisposeAll(); | ||
| 349 | + pyCollected += Finalizer.Instance.DisposeAll(disposeObj: obj, | ||
| 350 | + disposeDerived: derived, | ||
| 351 | + disposeBuffer: buffer); | ||
| 345 | 352 | } | |
| 346 | 353 | if (Volatile.Read(ref _collected) == 0 && pyCollected == 0) | |
| 347 | 354 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,10 +11,15 @@ internal sealed class CLRObject : ManagedType | |||
| 11 | 11 | { | |
| 12 | 12 | internal readonly object inst; | |
| 13 | 13 | ||
| 14 | + internal static bool creationBlocked = false; | ||
| 15 | + | ||
| 14 | 16 | // "borrowed" references | |
| 15 | 17 | internal static readonly HashSet<IntPtr> reflectedObjects = new(); | |
| 16 | 18 | static NewReference Create(object ob, BorrowedReference tp) | |
| 17 | 19 | { | |
| 20 | + if (creationBlocked) | ||
| 21 | + throw new InvalidOperationException("Reflected objects should not be created anymore."); | ||
| 22 | + | ||
| 18 | 23 | Debug.Assert(tp != null); | |
| 19 | 24 | var py = Runtime.PyType_GenericAlloc(tp, 0); | |
| 20 | 25 | ||
@@ -61,6 +66,9 @@ internal static void Restore(object ob, BorrowedReference pyHandle, Dictionary<s | |||
| 61 | 66 | ||
| 62 | 67 | protected override void OnLoad(BorrowedReference ob, Dictionary<string, object?>? context) | |
| 63 | 68 | { | |
| 69 | + if (creationBlocked) | ||
| 70 | + throw new InvalidOperationException("Reflected objects should not be loaded anymore."); | ||
| 71 | + | ||
| 64 | 72 | base.OnLoad(ob, context); | |
| 65 | 73 | GCHandle gc = GCHandle.Alloc(this); | |
| 66 | 74 | SetGCHandle(ob, gc); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments