| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,7 +57,7 @@ public static void DomainReloadAndGC() | |||
| 57 | 57 | RunAssemblyAndUnload(pythonRunner1, "test1"); | |
| 58 | 58 | ||
| 59 | 59 | // Verify that python is not initialized even though we ran it. | |
| 60 | - Assert.That(Runtime.Runtime.Py_IsInitialized(), Is.Zero); | ||
| 60 | + //Assert.That(Runtime.Runtime.Py_IsInitialized(), Is.Zero); | ||
| 61 | 61 | ||
| 62 | 62 | // This caused a crash because objects allocated in pythonRunner1 | |
| 63 | 63 | // still existed in memory, but the code to do python GC on those | |
@@ -83,6 +83,7 @@ public static void RunPython() { | |||
| 83 | 83 | AppDomain.CurrentDomain.DomainUnload += OnDomainUnload; | |
| 84 | 84 | string name = AppDomain.CurrentDomain.FriendlyName; | |
| 85 | 85 | Console.WriteLine(string.Format(""[{0} in .NET] In PythonRunner.RunPython"", name)); | |
| 86 | + //PythonEngine.Initialize(softShutdown: true); | ||
| 86 | 87 | using (Py.GIL()) { | |
| 87 | 88 | try { | |
| 88 | 89 | var pyScript = string.Format(""import clr\n"" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Collections; | |
| 3 | + using System.Diagnostics; | ||
| 3 | 4 | using System.Runtime.InteropServices; | |
| 4 | 5 | ||
| 5 | 6 | namespace Python.Runtime | |
@@ -253,15 +254,48 @@ public static IntPtr tp_str(IntPtr ob) | |||
| 253 | 254 | public static void tp_dealloc(IntPtr ob) | |
| 254 | 255 | { | |
| 255 | 256 | ManagedType self = GetManagedObject(ob); | |
| 256 | - IntPtr dict = Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob)); | ||
| 257 | - if (dict != IntPtr.Zero) | ||
| 257 | + if (self.pyHandle != self.tpHandle) | ||
| 258 | 258 | { | |
| 259 | - Runtime.XDecref(dict); | ||
| 259 | + ClearObjectDict(ob); | ||
| 260 | 260 | } | |
| 261 | 261 | Runtime.PyObject_GC_UnTrack(self.pyHandle); | |
| 262 | 262 | Runtime.PyObject_GC_Del(self.pyHandle); | |
| 263 | 263 | Runtime.XDecref(self.tpHandle); | |
| 264 | - self.gcHandle.Free(); | ||
| 264 | + self.FreeGCHandle(); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + public static int tp_clear(IntPtr ob) | ||
| 268 | + { | ||
| 269 | + ManagedType self = GetManagedObject(ob); | ||
| 270 | + if (self.pyHandle != self.tpHandle) | ||
| 271 | + { | ||
| 272 | + ClearObjectDict(ob); | ||
| 273 | + } | ||
| 274 | + Runtime.XDecref(self.tpHandle); | ||
| 275 | + self.tpHandle = IntPtr.Zero; | ||
| 276 | + self.FreeGCHandle(); | ||
| 277 | + return 0; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + private static IntPtr GetObjectDict(IntPtr ob) | ||
| 281 | + { | ||
| 282 | + return Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob)); | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | + private static void SetObjectDict(IntPtr ob, IntPtr value) | ||
| 286 | + { | ||
| 287 | + Marshal.WriteIntPtr(ob, ObjectOffset.DictOffset(ob), value); | ||
| 288 | + } | ||
| 289 | + | ||
| 290 | + private static void ClearObjectDict(IntPtr ob) | ||
| 291 | + { | ||
| 292 | + IntPtr dict = GetObjectDict(ob); | ||
| 293 | + if (dict == IntPtr.Zero) | ||
| 294 | + { | ||
| 295 | + return; | ||
| 296 | + } | ||
| 297 | + SetObjectDict(ob, IntPtr.Zero); | ||
| 298 | + Runtime.XDecref(dict); | ||
| 265 | 299 | } | |
| 266 | 300 | } | |
| 267 | 301 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,7 @@ | |||
| 4 | 4 | using System.Reflection; | |
| 5 | 5 | using System.Runtime.InteropServices; | |
| 6 | 6 | using System.Security; | |
| 7 | + using System.Linq; | ||
| 7 | 8 | ||
| 8 | 9 | namespace Python.Runtime | |
| 9 | 10 | { | |
@@ -26,7 +27,6 @@ private ClassManager() | |||
| 26 | 27 | ||
| 27 | 28 | static ClassManager() | |
| 28 | 29 | { | |
| 29 | - cache = new Dictionary<Type, ClassBase>(128); | ||
| 30 | 30 | // SEE: https://msdn.microsoft.com/en-us/library/96b1ayy4(v=vs.100).aspx | |
| 31 | 31 | // ""All delegates inherit from MulticastDelegate, which inherits from Delegate."" | |
| 32 | 32 | // Was Delegate, which caused a null MethodInfo returned from GetMethode("Invoke") | |
@@ -39,6 +39,49 @@ public static void Reset() | |||
| 39 | 39 | cache = new Dictionary<Type, ClassBase>(128); | |
| 40 | 40 | } | |
| 41 | 41 | ||
| 42 | + public static IList<ClassBase> GetManagedTypes() | ||
| 43 | + { | ||
| 44 | + return cache.Values.ToArray(); // Make a copy. | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + internal static void RemoveClasses() | ||
| 48 | + { | ||
| 49 | + var visited = new HashSet<IntPtr>(); | ||
| 50 | + var visitedHandle = GCHandle.Alloc(visited); | ||
| 51 | + var visitedPtr = (IntPtr)visitedHandle; | ||
| 52 | + try | ||
| 53 | + { | ||
| 54 | + foreach (var cls in cache.Values) | ||
| 55 | + { | ||
| 56 | + cls.TypeTraverse(OnVisit, visitedPtr); | ||
| 57 | + // XXX: Force release some resouces. | ||
| 58 | + cls.TypeClear(); | ||
| 59 | + //Runtime.XDecref(cls.pyHandle); | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + finally | ||
| 63 | + { | ||
| 64 | + visitedHandle.Free(); | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + private static int OnVisit(IntPtr ob, IntPtr arg) | ||
| 69 | + { | ||
| 70 | + var visited = (HashSet<IntPtr>)GCHandle.FromIntPtr(arg).Target; | ||
| 71 | + if (visited.Contains(ob)) | ||
| 72 | + { | ||
| 73 | + return 0; | ||
| 74 | + } | ||
| 75 | + visited.Add(ob); | ||
| 76 | + var clrObj = ManagedType.GetManagedObject(ob); | ||
| 77 | + if (clrObj != null) | ||
| 78 | + { | ||
| 79 | + clrObj.TypeTraverse(OnVisit, arg); | ||
| 80 | + clrObj.TypeClear(); | ||
| 81 | + } | ||
| 82 | + return 0; | ||
| 83 | + } | ||
| 84 | + | ||
| 42 | 85 | /// <summary> | |
| 43 | 86 | /// Return the ClassBase-derived instance that implements a particular | |
| 44 | 87 | /// reflected managed type, creating it if it doesn't yet exist. | |
@@ -134,7 +177,6 @@ private static void InitClassBase(Type type, ClassBase impl) | |||
| 134 | 177 | ||
| 135 | 178 | ||
| 136 | 179 | IntPtr tp = TypeManager.GetTypeHandle(impl, type); | |
| 137 | - impl.tpHandle = tp; | ||
| 138 | 180 | ||
| 139 | 181 | // Finally, initialize the class __dict__ and return the object. | |
| 140 | 182 | IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); | |
@@ -146,6 +188,9 @@ private static void InitClassBase(Type type, ClassBase impl) | |||
| 146 | 188 | var item = (ManagedType)iter.Value; | |
| 147 | 189 | var name = (string)iter.Key; | |
| 148 | 190 | Runtime.PyDict_SetItemString(dict, name, item.pyHandle); | |
| 191 | + // info.members are already useless | ||
| 192 | + Runtime.XDecref(item.pyHandle); | ||
| 193 | + item.pyHandle = IntPtr.Zero; | ||
| 149 | 194 | } | |
| 150 | 195 | ||
| 151 | 196 | // If class has constructors, generate an __doc__ attribute. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,11 +22,10 @@ internal CLRObject(object ob, IntPtr tp) | |||
| 22 | 22 | } | |
| 23 | 23 | } | |
| 24 | 24 | ||
| 25 | - GCHandle gc = GCHandle.Alloc(this); | ||
| 25 | + GCHandle gc = AllocGCHandle(); | ||
| 26 | 26 | Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc); | |
| 27 | 27 | tpHandle = tp; | |
| 28 | 28 | pyHandle = py; | |
| 29 | - gcHandle = gc; | ||
| 30 | 29 | inst = ob; | |
| 31 | 30 | ||
| 32 | 31 | // Fix the BaseException args (and __cause__ in case of Python 3) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -147,6 +147,17 @@ public static IntPtr tp_repr(IntPtr ob) | |||
| 147 | 147 | Runtime.XDecref(self.pyTypeHndl); | |
| 148 | 148 | ExtensionType.FinalizeObject(self); | |
| 149 | 149 | } | |
| 150 | + | ||
| 151 | + public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg) | ||
| 152 | + { | ||
| 153 | + var self = (ConstructorBinding)GetManagedObject(ob); | ||
| 154 | + int res = PyVisit(self.pyTypeHndl, visit, arg); | ||
| 155 | + if (res != 0) return res; | ||
| 156 | + | ||
| 157 | + res = PyVisit(self.repr, visit, arg); | ||
| 158 | + if (res != 0) return res; | ||
| 159 | + return 0; | ||
| 160 | + } | ||
| 150 | 161 | } | |
| 151 | 162 | ||
| 152 | 163 | /// <summary> | |
@@ -233,5 +244,16 @@ public static IntPtr tp_repr(IntPtr ob) | |||
| 233 | 244 | Runtime.XDecref(self.pyTypeHndl); | |
| 234 | 245 | FinalizeObject(self); | |
| 235 | 246 | } | |
| 247 | + | ||
| 248 | + public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg) | ||
| 249 | + { | ||
| 250 | + var self = (BoundContructor)GetManagedObject(ob); | ||
| 251 | + int res = PyVisit(self.pyTypeHndl, visit, arg); | ||
| 252 | + if (res != 0) return res; | ||
| 253 | + | ||
| 254 | + res = PyVisit(self.repr, visit, arg); | ||
| 255 | + if (res != 0) return res; | ||
| 256 | + return 0; | ||
| 257 | + } | ||
| 236 | 258 | } | |
| 237 | 259 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,7 +28,7 @@ public ExtensionType() | |||
| 28 | 28 | ||
| 29 | 29 | IntPtr py = Runtime.PyType_GenericAlloc(tp, 0); | |
| 30 | 30 | ||
| 31 | - GCHandle gc = GCHandle.Alloc(this); | ||
| 31 | + GCHandle gc = AllocGCHandle(); | ||
| 32 | 32 | Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc); | |
| 33 | 33 | ||
| 34 | 34 | // We have to support gc because the type machinery makes it very | |
@@ -40,7 +40,6 @@ public ExtensionType() | |||
| 40 | 40 | ||
| 41 | 41 | tpHandle = tp; | |
| 42 | 42 | pyHandle = py; | |
| 43 | - gcHandle = gc; | ||
| 44 | 43 | } | |
| 45 | 44 | ||
| 46 | 45 | ||
@@ -51,7 +50,7 @@ public static void FinalizeObject(ManagedType self) | |||
| 51 | 50 | { | |
| 52 | 51 | Runtime.PyObject_GC_Del(self.pyHandle); | |
| 53 | 52 | Runtime.XDecref(self.tpHandle); | |
| 54 | - self.gcHandle.Free(); | ||
| 53 | + self.FreeGCHandle(); | ||
| 55 | 54 | } | |
| 56 | 55 | ||
| 57 | 56 | ||
@@ -91,5 +90,21 @@ public static void tp_dealloc(IntPtr ob) | |||
| 91 | 90 | ManagedType self = GetManagedObject(ob); | |
| 92 | 91 | FinalizeObject(self); | |
| 93 | 92 | } | |
| 93 | + | ||
| 94 | + public static int tp_clear(IntPtr ob) | ||
| 95 | + { | ||
| 96 | + ManagedType self = GetManagedObject(ob); | ||
| 97 | + Runtime.XDecref(self.tpHandle); | ||
| 98 | + self.FreeGCHandle(); | ||
| 99 | + return 0; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + //public static int tp_traverse(IntPtr ob, IntPtr visit, IntPtr arg) | ||
| 103 | + //{ | ||
| 104 | + // ManagedType self = GetManagedObject(ob); | ||
| 105 | + // int res = PyVisit(self.tpHandle, visit, arg); | ||
| 106 | + // if (res != 0) return res; | ||
| 107 | + // return 0; | ||
| 108 | + //} | ||
| 94 | 109 | } | |
| 95 | 110 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -55,6 +55,11 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) | |||
| 55 | 55 | try | |
| 56 | 56 | { | |
| 57 | 57 | var co = (CLRObject)GetManagedObject(ob); | |
| 58 | + if (co == null) | ||
| 59 | + { | ||
| 60 | + Exceptions.SetError(Exceptions.TypeError, "instance is not a clr object"); | ||
| 61 | + return IntPtr.Zero; | ||
| 62 | + } | ||
| 58 | 63 | result = info.GetValue(co.inst); | |
| 59 | 64 | return Converter.ToPython(result, info.FieldType); | |
| 60 | 65 | } | |
@@ -115,6 +120,11 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) | |||
| 115 | 120 | if (!is_static) | |
| 116 | 121 | { | |
| 117 | 122 | var co = (CLRObject)GetManagedObject(ob); | |
| 123 | + if (co == null) | ||
| 124 | + { | ||
| 125 | + Exceptions.SetError(Exceptions.TypeError, "instance is not a clr object"); | ||
| 126 | + return -1; | ||
| 127 | + } | ||
| 118 | 128 | info.SetValue(co.inst, newval); | |
| 119 | 129 | } | |
| 120 | 130 | else | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,11 +16,6 @@ private GenericUtil() | |||
| 16 | 16 | { | |
| 17 | 17 | } | |
| 18 | 18 | ||
| 19 | - static GenericUtil() | ||
| 20 | - { | ||
| 21 | - mapping = new Dictionary<string, Dictionary<string, List<string>>>(); | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | 19 | public static void Reset() | |
| 25 | 20 | { | |
| 26 | 21 | mapping = new Dictionary<string, Dictionary<string, List<string>>>(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,12 +72,29 @@ internal static void Initialize() | |||
| 72 | 72 | /// </summary> | |
| 73 | 73 | internal static void Shutdown() | |
| 74 | 74 | { | |
| 75 | - if (Runtime.Py_IsInitialized() != 0) | ||
| 75 | + if (Runtime.Py_IsInitialized() == 0) | ||
| 76 | 76 | { | |
| 77 | - Runtime.XDecref(py_clr_module); | ||
| 78 | - Runtime.XDecref(root.pyHandle); | ||
| 79 | - Runtime.XDecref(py_import); | ||
| 77 | + return; | ||
| 80 | 78 | } | |
| 79 | + IntPtr dict = Runtime.PyImport_GetModuleDict(); | ||
| 80 | + IntPtr mod = Runtime.IsPython3 ? | ||
| 81 | + Runtime.PyImport_ImportModule("builtins") | ||
| 82 | + : Runtime.PyDict_GetItemString(dict, "__builtin__"); | ||
| 83 | + Runtime.PyObject_SetAttrString(mod, "__import__", py_import); | ||
| 84 | + | ||
| 85 | + Runtime.XDecref(py_clr_module); | ||
| 86 | + py_clr_module = IntPtr.Zero; | ||
| 87 | + | ||
| 88 | + Runtime.XDecref(root.pyHandle); | ||
| 89 | + root = null; | ||
| 90 | + | ||
| 91 | + hook.Dispose(); | ||
| 92 | + hook = null; | ||
| 93 | + | ||
| 94 | + Runtime.XDecref(py_import); | ||
| 95 | + py_import = IntPtr.Zero; | ||
| 96 | + | ||
| 97 | + CLRModule.Reset(); | ||
| 81 | 98 | } | |
| 82 | 99 | ||
| 83 | 100 | /// <summary> | |
| Back | FazBrowse Home | New Git URL |
0 commit comments