by
Changes to one file · Browse files at 0a84cfa83687 Showing diff from parent 4fce6bab3840 b5fbaedfb641 Diff from another changeset...
@@ -18,6 +18,7 @@ import subprocess
import traceback
import zlib
+import gc
from PyQt4.QtCore import *
from PyQt4.QtGui import *
@@ -364,6 +365,52 @@ else:
return checkargs()
+class GarbageCollector(QObject):
+ '''
+ Disable automatic garbage collection and instead collect manually
+ every INTERVAL milliseconds.
+
+ This is done to ensure that garbage collection only happens in the GUI
+ thread, as otherwise Qt can crash.
+ '''
+
+ INTERVAL = 5000
+
+ def __init__(self, parent, debug=False):
+ QObject.__init__(self, parent)
+ self.debug = debug
+
+ self.timer = QTimer(self)
+ self.timer.timeout.connect(self.check)
+
+ self.threshold = gc.get_threshold()
+ gc.disable()
+ self.timer.start(self.INTERVAL)
+ #gc.set_debug(gc.DEBUG_SAVEALL)
+
+ def check(self):
+ #return self.debug_cycles()
+ l0, l1, l2 = gc.get_count()
+ if self.debug:
+ print 'gc_check called:', l0, l1, l2
+ if l0 > self.threshold[0]:
+ num = gc.collect(0)
+ if self.debug:
+ print 'collecting gen 0, found:', num, 'unreachable'
+ if l1 > self.threshold[1]:
+ num = gc.collect(1)
+ if self.debug:
+ print 'collecting gen 1, found:', num, 'unreachable'
+ if l2 > self.threshold[2]:
+ num = gc.collect(2)
+ if self.debug:
+ print 'collecting gen 2, found:', num, 'unreachable'
+
+ def debug_cycles(self):
+ gc.collect()
+ for obj in gc.garbage:
+ print (obj, repr(obj), type(obj))
+
class _QtRunner(QObject):
"""Run Qt app and hold its windows
@@ -389,6 +436,8 @@
def __init__(self):
super(_QtRunner, self).__init__()
+ gc.disable()
+ self.debug = 'THGDEBUG' in os.environ
self._mainapp = None
self._dialogs = []
self.errors = []
@@ -470,6 +519,7 @@ QSettings.setDefaultFormat(QSettings.IniFormat)
self._mainapp = QApplication(sys.argv)
+ self._gc = GarbageCollector(self, self.debug)
try:
# default org is used by QSettings
self._mainapp.setApplicationName('TortoiseHgQt')
|
Loading...