mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 11:28:17 -04:00
prevent garbage leak
This commit is contained in:
parent
93a5850c7b
commit
a86451ad35
@ -62,6 +62,12 @@ class EnforcesCalldowns:
|
|||||||
if EnforcesCalldowns.notActive():
|
if EnforcesCalldowns.notActive():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# protect against multiple calldowns via multiple inheritance
|
||||||
|
if hasattr(self, '_numInits'):
|
||||||
|
self._numInits += 1
|
||||||
|
else:
|
||||||
|
self._numInits = 1
|
||||||
|
|
||||||
# this map tracks how many times each func has been called
|
# this map tracks how many times each func has been called
|
||||||
self._funcId2calls = {}
|
self._funcId2calls = {}
|
||||||
# this map tracks the 'latch' values for each func; if the call count
|
# this map tracks the 'latch' values for each func; if the call count
|
||||||
@ -105,12 +111,21 @@ class EnforcesCalldowns:
|
|||||||
if EnforcesCalldowns.notActive():
|
if EnforcesCalldowns.notActive():
|
||||||
return
|
return
|
||||||
# this must be called on destruction to prevent memory leaks
|
# this must be called on destruction to prevent memory leaks
|
||||||
|
# protect against multiple calldowns via multiple inheritance
|
||||||
|
assert hasattr(self, '_numInits'), (
|
||||||
|
'too many calls to EnforcesCalldowns.EC_destroy, class=%s' % self.__class__.__name__)
|
||||||
|
if self._numInits == 1:
|
||||||
for name in self._obscuredMethodNames:
|
for name in self._obscuredMethodNames:
|
||||||
|
# Functors need to be destroyed to prevent garbage leaks
|
||||||
|
getattr(self, name).destroy()
|
||||||
delattr(self, name)
|
delattr(self, name)
|
||||||
del self._obscuredMethodNames
|
del self._obscuredMethodNames
|
||||||
# this opens up more cans of worms. Let's keep it closed for the moment
|
# this opens up more cans of worms. Let's keep it closed for the moment
|
||||||
#del self._funcId2calls
|
#del self._funcId2calls
|
||||||
#del self._funcId2latch
|
#del self._funcId2latch
|
||||||
|
del self._numInits
|
||||||
|
else:
|
||||||
|
self._numInits -= 1
|
||||||
|
|
||||||
def skipCalldown(self, method):
|
def skipCalldown(self, method):
|
||||||
if EnforcesCalldowns.notActive():
|
if EnforcesCalldowns.notActive():
|
||||||
@ -164,15 +179,35 @@ if not EnforcesCalldowns.notActive():
|
|||||||
class CalldownEnforceTestSubclass(CalldownEnforceTest):
|
class CalldownEnforceTestSubclass(CalldownEnforceTest):
|
||||||
def testFunc(self):
|
def testFunc(self):
|
||||||
CalldownEnforceTest.testFunc(self)
|
CalldownEnforceTest.testFunc(self)
|
||||||
|
def destroy(self):
|
||||||
|
CalldownEnforceTest.EC_destroy(self)
|
||||||
class CalldownEnforceTestSubclassFail(CalldownEnforceTest):
|
class CalldownEnforceTestSubclassFail(CalldownEnforceTest):
|
||||||
def testFunc(self):
|
def testFunc(self):
|
||||||
pass
|
pass
|
||||||
class CalldownEnforceTestSubclassSkip(CalldownEnforceTest):
|
class CalldownEnforceTestSubclassSkip(CalldownEnforceTest):
|
||||||
def testFunc(self):
|
def testFunc(self):
|
||||||
self.skipCalldown(CalldownEnforceTest.testFunc)
|
self.skipCalldown(CalldownEnforceTest.testFunc)
|
||||||
|
class CalldownEnforceTestSubclass2(CalldownEnforceTest):
|
||||||
|
def testFunc(self):
|
||||||
|
CalldownEnforceTest.testFunc(self)
|
||||||
|
def destroy(self):
|
||||||
|
CalldownEnforceTest.EC_destroy(self)
|
||||||
|
class CalldownEnforceTestDiamond(CalldownEnforceTestSubclass,
|
||||||
|
CalldownEnforceTestSubclass2):
|
||||||
|
def __init__(self):
|
||||||
|
CalldownEnforceTestSubclass.__init__(self)
|
||||||
|
CalldownEnforceTestSubclass2.__init__(self)
|
||||||
|
def testFunc(self):
|
||||||
|
CalldownEnforceTestSubclass.testFunc(self)
|
||||||
|
CalldownEnforceTestSubclass2.testFunc(self)
|
||||||
|
def destroy(self):
|
||||||
|
CalldownEnforceTestSubclass.destroy(self)
|
||||||
|
CalldownEnforceTestSubclass2.destroy(self)
|
||||||
|
|
||||||
cets = CalldownEnforceTestSubclass()
|
cets = CalldownEnforceTestSubclass()
|
||||||
cetsf = CalldownEnforceTestSubclassFail()
|
cetsf = CalldownEnforceTestSubclassFail()
|
||||||
cetss = CalldownEnforceTestSubclassSkip()
|
cetss = CalldownEnforceTestSubclassSkip()
|
||||||
|
cetd = CalldownEnforceTestDiamond()
|
||||||
raised = False
|
raised = False
|
||||||
try:
|
try:
|
||||||
cets.testFunc()
|
cets.testFunc()
|
||||||
@ -194,12 +229,26 @@ if not EnforcesCalldowns.notActive():
|
|||||||
raised = True
|
raised = True
|
||||||
if raised:
|
if raised:
|
||||||
raise "calldownEnforced.skipCalldown raised when it shouldn't"
|
raise "calldownEnforced.skipCalldown raised when it shouldn't"
|
||||||
|
raised = False
|
||||||
|
cetd.testFunc()
|
||||||
|
msg = ''
|
||||||
|
try:
|
||||||
|
# make sure we're OK to call down to destroy multiple times
|
||||||
|
cetd.destroy()
|
||||||
|
except Exception, e:
|
||||||
|
msg = str(e)
|
||||||
|
raised = True
|
||||||
|
if raised:
|
||||||
|
raise "calldownEnforcedDiamond.destroy raised when it shouldn't\n%s" % msg
|
||||||
cetss.EC_destroy()
|
cetss.EC_destroy()
|
||||||
cetsf.EC_destroy()
|
cetsf.EC_destroy()
|
||||||
cets.EC_destroy()
|
cets.EC_destroy()
|
||||||
|
del cetd
|
||||||
del cetss
|
del cetss
|
||||||
del cetsf
|
del cetsf
|
||||||
del cets
|
del cets
|
||||||
|
del CalldownEnforceTestDiamond
|
||||||
|
del CalldownEnforceTestSubclass2
|
||||||
del CalldownEnforceTestSubclassSkip
|
del CalldownEnforceTestSubclassSkip
|
||||||
del CalldownEnforceTestSubclassFail
|
del CalldownEnforceTestSubclassFail
|
||||||
del CalldownEnforceTestSubclass
|
del CalldownEnforceTestSubclass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user