summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-03-30 19:15:41 +0200
committerhut <hut@lavabit.com>2010-03-30 19:15:41 +0200
commit9b83f1144024c98cad6ece752b7e625bfec608f2 (patch)
tree3cfa1e12d79719dd7ebf27e3efbbee0f82359a70
parentd1fc886688016e97af8f1dbe74e5b2c04649e08b (diff)
downloadranger-9b83f1144024c98cad6ece752b7e625bfec608f2.tar.gz
fixed memory leak
-rw-r--r--ranger/core/actions.py2
-rw-r--r--ranger/core/environment.py12
-rw-r--r--ranger/core/fm.py3
-rw-r--r--ranger/fsobject/directory.py49
-rw-r--r--ranger/fsobject/fsobject.py9
-rw-r--r--ranger/gui/widgets/browsercolumn.py5
-rw-r--r--ranger/shared/settings.py8
7 files changed, 53 insertions, 35 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 6f2b8606..6eef3d41 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -305,7 +305,7 @@ class Actions(EnvironmentAware, SettingsAware):
 	def reset(self):
 		"""Reset the filemanager, clearing the directory buffer"""
 		old_path = self.env.cwd.path
-		self.env.directories = {}
+		self.env.garbage_collect(-1)
 		self.enter_dir(old_path)
 
 	def toggle_boolean_option(self, string):
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index 8799229c..cdca9782 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -100,14 +100,14 @@ class Environment(SettingsAware):
 			except KeyError:
 				return directory
 
-	def garbage_collect(self):
+	def garbage_collect(self, age):
 		"""Delete unused directory objects"""
-		from ranger.fsobject.fsobject import FileSystemObject
-		for key in tuple(self.directories.keys()):
+		for key in tuple(self.directories):
 			value = self.directories[key]
-			if isinstance(value, FileSystemObject):
-				if value.is_older_than(1200) and not value in self.pathway:
-					del self.directories[key]
+			if value.is_older_than(age): # and not value in self.pathway:
+				del self.directories[key]
+				if value.is_directory:
+					value.files = None
 
 	def get_selection(self):
 		if self.cwd:
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index aef10150..de22a86c 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -32,6 +32,7 @@ from ranger.fsobject import Loader
 
 CTRL_C = 3
 TICKS_BEFORE_COLLECTING_GARBAGE = 100
+TIME_BEFORE_FILE_BECOMES_GARBAGE = 1200
 
 class FM(Actions, SignalDispatcher):
 	input_blocked = False
@@ -141,7 +142,7 @@ class FM(Actions, SignalDispatcher):
 				gc_tick += 1
 				if gc_tick > TICKS_BEFORE_COLLECTING_GARBAGE:
 					gc_tick = 0
-					env.garbage_collect()
+					env.garbage_collect(TIME_BEFORE_FILE_BECOMES_GARBAGE)
 
 		except KeyboardInterrupt:
 			# this only happens in --debug mode. By default, interrupts
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index 3ceaaa79..eb031ffe 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -58,10 +58,9 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 	last_update_time = -1
 	load_content_mtime = -1
 
+	order_outdated = False
+	content_outdated = False
 	old_show_hidden = None
-	old_sort_directories_first = None
-	old_sort_reverse = None
-	old_sort = None
 	old_filter = None
 	old_hidden_filter = None
 
@@ -85,12 +84,32 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 		# to find out if something has changed:
 		self.old_show_hidden = self.settings.show_hidden
-		self.old_sort_directories_first = self.settings.sort_directories_first
-		self.old_sort = self.settings.sort
 		self.old_filter = self.filter
 		self.old_hidden_filter = self.settings.hidden_filter
-		self.old_sort_reverse = self.settings.sort_reverse
-		self.old_sort_case_insensitive = self.settings.sort_case_insensitive
+
+		self.handlers = []
+		lst = ('sort_directories_first', 'sort', 'sort_reverse',
+				'sort_case_insensitive')
+		for opt in lst:
+			self.handlers.append(self.settings.signal_bind('setopt.' + opt,
+					self.request_resort, weak=True))
+
+		lst = ('filter', 'hidden_filter', 'show_hidden')
+		for opt in lst:
+			self.handlers.append(self.settings.signal_bind('setopt.' + opt,
+				self.request_reload, weak=True))
+
+	def __del__(self):
+		log("freeing {0}".format(self))
+		for handler in self.handlers:
+			self.settings.signal_unbind(handler)
+
+	def request_resort(self):
+		self.order_outdated = True
+
+	def request_reload(self):
+#		log("request a reload for {0}".format(self))
+		self.content_outdated = True
 
 	def get_list(self):
 		return self.files
@@ -295,12 +314,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 	def sort_if_outdated(self):
 		"""Sort the containing files if they are outdated"""
-		if self.old_sort_directories_first != \
-				self.settings.sort_directories_first \
-				or self.old_sort != self.settings.sort \
-				or self.old_sort_reverse != self.settings.sort_reverse \
-				or self.old_sort_case_insensitive != \
-				self.settings.sort_case_insensitive:
+		if self.order_outdated:
+			self.order_outdated = False
 			self.sort()
 			return True
 		return False
@@ -375,12 +390,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 		if self.load_content_once(*a, **k): return True
 
-		if self.old_show_hidden != self.settings.show_hidden or \
-				self.old_filter != self.filter or \
-				self.old_hidden_filter != self.settings.hidden_filter:
-			self.old_filter = self.filter
-			self.old_hidden_filter = self.settings.hidden_filter
-			self.old_show_hidden = self.settings.show_hidden
+		if self.content_outdated:
+			self.content_outdated = False
 			self.load_content(*a, **k)
 			return True
 
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 4278c3e8..6933b18d 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -17,6 +17,8 @@ CONTAINER_EXTENSIONS = 'rar zip tar gz bz bz2 tgz 7z iso cab'.split()
 DOCUMENT_EXTENSIONS = 'pdf doc ppt odt'.split()
 DOCUMENT_BASENAMES = 'README TODO LICENSE COPYING INSTALL'.split()
 
+import time
+from ranger import log
 from . import T_FILE, T_DIRECTORY, T_UNKNOWN, T_NONEXISTANT, BAD_INFO
 from ranger.shared import MimeTypeAware, FileManagerAware
 from ranger.ext.shell_escape import shell_escape
@@ -81,6 +83,9 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		self.set_mimetype()
 		self.use()
 
+	def __repr__(self):
+		return "<{0} {1}>".format(self.__class__.__name__, self.path)
+
 	@property
 	def shell_escaped_basename(self):
 		if self._shell_escaped_basename is None:
@@ -109,12 +114,12 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 
 	def use(self):
 		"""mark the filesystem-object as used at the current time"""
-		import time
 		self.last_used = time.time()
 
 	def is_older_than(self, seconds):
 		"""returns whether this object wasn't use()d in the last n seconds"""
-		import time
+		if seconds < 0:
+			return True
 		return self.last_used + seconds < time.time()
 
 	def set_mimetype(self):
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 7de716c7..6f414cf6 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -133,6 +133,9 @@ class BrowserColumn(Pager):
 			self.need_redraw = True
 			self.old_dir = self.target
 
+		if self.target:  # don't garbage collect this directory please
+			self.target.use()
+
 		if self.target and self.target.is_directory \
 				and (self.level <= 0 or self.settings.preview_directories):
 			if self.target.pointed_obj != self.old_cf:
@@ -202,8 +205,6 @@ class BrowserColumn(Pager):
 
 		base_color = ['in_browser']
 
-		self.target.use()
-
 		self.win.move(0, 0)
 
 		if not self.target.content_loaded:
diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py
index 9c005e29..55259218 100644
--- a/ranger/shared/settings.py
+++ b/ranger/shared/settings.py
@@ -63,10 +63,10 @@ class SettingObject(SignalDispatcher):
 			assert self._check_type(name, value)
 			kws = dict(setting=name, value=value,
 					previous=self._settings[name])
-			self.signal_bind('core.setting.'+name,
+			self.signal_bind('setopt.'+name,
 					self._raw_set_with_signal, priority=0.2)
-			self.signal_emit('core.setting', **kws)
-			self.signal_emit('core.setting.'+name, **kws)
+			self.signal_emit('setopt', **kws)
+			self.signal_emit('setopt.'+name, **kws)
 
 	def __getattr__(self, name):
 		assert name in ALLOWED_SETTINGS or name in self._settings, \
@@ -117,7 +117,7 @@ class SettingsAware(object):
 		settings = SettingObject()
 
 		from ranger.gui.colorscheme import _colorscheme_name_to_class
-		settings.signal_bind('core.setting.colorscheme',
+		settings.signal_bind('setopt.colorscheme',
 				_colorscheme_name_to_class, priority=1)
 
 		from ranger.defaults import options as default_options