From a9f324230517d35493f04f1936d35cab64be7c46 Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Wed, 21 Jan 2009 23:49:33 +0000 Subject: [PATCH] check for garbage leaks in dev on window close and defocus, check on both client and AI --- .../src/distributed/ConnectionRepository.py | 20 +++----------- direct/src/showbase/GarbageReport.py | 26 +++++++++++++++++++ direct/src/showbase/ShowBase.py | 11 ++++++++ 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/direct/src/distributed/ConnectionRepository.py b/direct/src/distributed/ConnectionRepository.py index 8f580ad21a..77f1c3cd3e 100644 --- a/direct/src/distributed/ConnectionRepository.py +++ b/direct/src/distributed/ConnectionRepository.py @@ -51,9 +51,6 @@ class ConnectionRepository( if self.config.GetBool('verbose-repository'): self.setVerbose(1) - self._allowGarbageCycles = self.config.GetBool( - 'allow-garbage-cycles', 1) - # Set this to 'http' to establish a connection to the server # using the HTTPClient interface, which ultimately uses the # OpenSSL socket library (even though SSL is not involved). @@ -137,7 +134,9 @@ class ConnectionRepository( def _adjustGcThreshold(self, task): # do an unconditional collect to make sure gc.garbage has a chance to be # populated before we start increasing the auto-collect threshold - leakExists = self._checkForGarbageLeak() + # don't distribute the leak check from the client to the AI, they both + # do these garbage checks independently over time + leakExists = GarbageReport.checkForGarbageLeaks() if not leakExists: self.gcNotify.debug('no garbage found, doubling gc threshold') a, b, c = gc.get_threshold() @@ -154,19 +153,6 @@ class ConnectionRepository( return retVal - def _checkForGarbageLeak(self): - # does a garbage collect - # returns True if there is a garbage leak, False otherwise - # logs leak info and terminates (if configured to do so) - gc.collect() - leakExists = (len(gc.garbage) > 0) - if leakExists and (not self._allowGarbageCycles): - print - gr = GarbageReport.GarbageLogger('found garbage', threaded=False) - print - self.notify.error('%s garbage cycles found, see info above' % gr.getNumCycles()) - return leakExists - def generateGlobalObject(self, doId, dcname, values=None): def applyFieldValues(distObj, dclass, values): for i in range(dclass.getNumInheritedFields()): diff --git a/direct/src/showbase/GarbageReport.py b/direct/src/showbase/GarbageReport.py index 83dd2be03d..8ed2afc3d2 100755 --- a/direct/src/showbase/GarbageReport.py +++ b/direct/src/showbase/GarbageReport.py @@ -513,3 +513,29 @@ class GarbageLogger(GarbageReport): kArgs['log'] = True kArgs['autoDestroy'] = True GarbageReport.__init__(self, name, *args, **kArgs) + +def checkForGarbageLeaks(): + gc.collect() + leakExists = (len(gc.garbage) > 0) + if leakExists and (not config.GetBool('allow-garbage-cycles', 1)): + print + gr = GarbageLogger('found garbage', threaded=False) + print + notify = directNotify.newCategory("GarbageDetect") + notify.error('%s garbage cycles found, see info above' % gr.getNumCycles()) + return leakExists + +def b_checkForGarbageLeaks(): + # does a garbage collect + # returns True if there is a garbage leak, False otherwise + # logs leak info and terminates (if configured to do so) + try: + # if this is the client, tell the AI to check for leaks too + base.cr.timeManager + except: + pass + else: + if base.cr.timeManager: + base.cr.timeManager.d_checkForGarbageLeaks() + checkForGarbageLeaks() + diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index ec5ccf5835..f180ed9329 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -29,6 +29,7 @@ from InputStateGlobal import inputState from direct.showbase.BufferViewer import BufferViewer from direct.task import Task from direct.directutil import Verify +from direct.showbase import GarbageReport import EventManager import math,sys,os import Loader @@ -137,6 +138,7 @@ class ShowBase(DirectObject.DirectObject): self.winList = [] self.winControls = [] self.mainWinMinimized = 0 + self.mainWinForeground = 0 self.pipe = None self.pipeList = [] self.mouse2cam = None @@ -2181,8 +2183,17 @@ class ShowBase(DirectObject.DirectObject): if not properties.getOpen(): # If the user closes the main window, we should exit. self.notify.info("User closed main window.") + if __dev__: + GarbageReport.b_checkForGarbageLeaks() self.userExit() + if properties.getForeground() and not self.mainWinForeground: + self.mainWinForeground = 1 + elif not properties.getForeground() and self.mainWinForeground: + self.mainWinForeground = 0 + if __dev__: + GarbageReport.b_checkForGarbageLeaks() + if properties.getMinimized() and not self.mainWinMinimized: # If the main window is minimized, throw an event to # stop the music.