def __init__(self, name, firstCheckDelay = None): Job.__init__(self, name) self._serialNum = serialNum() self._findContainersJob = None self._checkContainersJob = None self._pruneContainersJob = None if firstCheckDelay is None: firstCheckDelay = 60. * 15. # divide by two, since the first check just takes length measurements and # doesn't check for leaks self._nextCheckDelay = firstCheckDelay/2. self._checkDelayScale = config.GetFloat('leak-detector-check-delay-scale', 1.5) self._pruneTaskPeriod = config.GetFloat('leak-detector-prune-period', 60. * 30.) # main dict of id(container)->containerRef self._id2ref = {} # storage for results of check-container job self._index2containerId2len = {} self._index2delay = {} if config.GetBool('leak-container', 0): _createContainerLeak() if config.GetBool('leak-tasks', 0): _createTaskLeak() # don't check our own tables for leaks ContainerLeakDetector.addPrivateObj(ContainerLeakDetector.PrivateIds) ContainerLeakDetector.addPrivateObj(self.__dict__) self.setPriority(Job.Priorities.Min) jobMgr.add(self)
def leakTask(task=None, leakTaskName=leakTaskName): base = getBase() taskMgr.add(nullTask, uniqueName(leakTaskName)) taskMgr.doMethodLater(1 << 31, nullDoLater, uniqueName(leakDoLaterName)) taskMgr.doMethodLater(10, leakTask, 'doLeakTask-%s' % serialNum()) if task: return task.done
def leakContainer(task=None): base = getBase() if not hasattr(base, 'leakContainer'): base.leakContainer = {} # use tuples as keys since they can't be weakref'd, and use an instance # since it can't be repr/eval'd # that will force the leak detector to hold a normal 'non-weak' reference class LeakKey: pass base.leakContainer[(LeakKey(),)] = {} # test the non-weakref object reference handling if random.random() < .01: key = random.choice(base.leakContainer.keys()) ContainerLeakDetector.notify.debug( 'removing reference to leakContainer key %s so it will be garbage-collected' % safeRepr(key)) del base.leakContainer[key] taskMgr.doMethodLater(10, leakContainer, 'leakContainer-%s' % serialNum()) if task: return task.done