def testStoreBridge(self): allocator = HGlobalAllocator() mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) try: def do(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) self.assertEquals(mapper.Retrieve(ptr), obj, "object not stored") self.assertEquals(mapper.Store(obj), ptr, "object not reverse-mapped") mapper.Weaken(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.IncRef(ptr) del obj return ref ref = do() gcwait() self.assertEquals(ref.IsAlive, True, "was not strengthened by IncRef") mapper.DecRef(ptr) gcwait() self.assertEquals(ref.IsAlive, False, "was not weakened by DecRef") finally: # need to dealloc ptr ourselves, it doesn't happen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testReleaseGILChecksBridgePtrs(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # force no throttling of cleanup mapper.GCThreshold = 0 def do1(): obj = object() ref = WeakReference(obj) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 2) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) # refcount > 1 means ref should have been strengthened del obj return ref, ptr ref, ptr = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was reaped unexpectedly (refcount was 2)") CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) mapper.EnsureGIL() mapper.ReleaseGIL() # refcount < 2 should have been weakened gcwait() self.assertRaises(NullReferenceException, mapper.Retrieve, ptr) # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()
def testStrengthenWeakenUnmanagedInstance(self): frees = [] allocator = GetAllocatingTestAllocator([], frees) mapper = PythonMapper(allocator) deallocTypes = CreateTypes(mapper) # need to use same allocator as mapper, otherwise it gets upset on shutdown ptr = allocator.Alloc(Marshal.SizeOf(PyObject)) try: def do1(): # see NOTE in interestingptrmaptest obj = object() ref = WeakReference(obj) CPyMarshal.WriteIntField(ptr, PyObject, "ob_refcnt", 1) CPyMarshal.WritePtrField(ptr, PyObject, "ob_type", mapper.PyBaseObject_Type) mapper.StoreBridge(ptr, obj) del obj return ref ref = do1() gcwait() self.assertEquals(ref.IsAlive, True, "was not strongly referenced") def do2(): obj = ref.Target mapper.Weaken(obj) del obj do2() gcwait() self.assertRaises(NullReferenceException, mapper.Retrieve, ptr) finally: # need to dealloc ptr ourselves, it doesn't hapen automatically # except for objects with Dispatchers mapper.IC_PyBaseObject_Dealloc(ptr) mapper.Dispose() deallocTypes()