Browse Source

check for garbage leaks in dev on window close and defocus, check on both client and AI

Darren Ranalli 17 years ago
parent
commit
a9f3242305

+ 3 - 17
direct/src/distributed/ConnectionRepository.py

@@ -51,9 +51,6 @@ class ConnectionRepository(
         if self.config.GetBool('verbose-repository'):
         if self.config.GetBool('verbose-repository'):
             self.setVerbose(1)
             self.setVerbose(1)
 
 
-        self._allowGarbageCycles = self.config.GetBool(
-            'allow-garbage-cycles', 1)
-
         # Set this to 'http' to establish a connection to the server
         # Set this to 'http' to establish a connection to the server
         # using the HTTPClient interface, which ultimately uses the
         # using the HTTPClient interface, which ultimately uses the
         # OpenSSL socket library (even though SSL is not involved).
         # OpenSSL socket library (even though SSL is not involved).
@@ -137,7 +134,9 @@ class ConnectionRepository(
     def _adjustGcThreshold(self, task):
     def _adjustGcThreshold(self, task):
         # do an unconditional collect to make sure gc.garbage has a chance to be
         # do an unconditional collect to make sure gc.garbage has a chance to be
         # populated before we start increasing the auto-collect threshold
         # 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:
         if not leakExists:
             self.gcNotify.debug('no garbage found, doubling gc threshold')
             self.gcNotify.debug('no garbage found, doubling gc threshold')
             a, b, c = gc.get_threshold()
             a, b, c = gc.get_threshold()
@@ -154,19 +153,6 @@ class ConnectionRepository(
 
 
         return retVal
         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 generateGlobalObject(self, doId, dcname, values=None):
         def applyFieldValues(distObj, dclass, values):
         def applyFieldValues(distObj, dclass, values):
             for i in range(dclass.getNumInheritedFields()):
             for i in range(dclass.getNumInheritedFields()):

+ 26 - 0
direct/src/showbase/GarbageReport.py

@@ -513,3 +513,29 @@ class GarbageLogger(GarbageReport):
         kArgs['log'] = True
         kArgs['log'] = True
         kArgs['autoDestroy'] = True
         kArgs['autoDestroy'] = True
         GarbageReport.__init__(self, name, *args, **kArgs)
         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()
+    

+ 11 - 0
direct/src/showbase/ShowBase.py

@@ -29,6 +29,7 @@ from InputStateGlobal import inputState
 from direct.showbase.BufferViewer import BufferViewer
 from direct.showbase.BufferViewer import BufferViewer
 from direct.task import Task
 from direct.task import Task
 from direct.directutil import Verify
 from direct.directutil import Verify
+from direct.showbase import GarbageReport
 import EventManager
 import EventManager
 import math,sys,os
 import math,sys,os
 import Loader
 import Loader
@@ -137,6 +138,7 @@ class ShowBase(DirectObject.DirectObject):
         self.winList = []
         self.winList = []
         self.winControls = []
         self.winControls = []
         self.mainWinMinimized = 0
         self.mainWinMinimized = 0
+        self.mainWinForeground = 0
         self.pipe = None
         self.pipe = None
         self.pipeList = []
         self.pipeList = []
         self.mouse2cam = None
         self.mouse2cam = None
@@ -2181,8 +2183,17 @@ class ShowBase(DirectObject.DirectObject):
             if not properties.getOpen():
             if not properties.getOpen():
                 # If the user closes the main window, we should exit.
                 # If the user closes the main window, we should exit.
                 self.notify.info("User closed main window.")
                 self.notify.info("User closed main window.")
+                if __dev__:
+                    GarbageReport.b_checkForGarbageLeaks()
                 self.userExit()
                 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 properties.getMinimized() and not self.mainWinMinimized:
                 # If the main window is minimized, throw an event to
                 # If the main window is minimized, throw an event to
                 # stop the music.
                 # stop the music.