summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2019-02-26 14:27:43 +0000
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2019-02-27 10:57:55 +0000
commitd55039c33685d267fd8834ecc5d16030c1385325 (patch)
tree4e9b7af191965aa9c4e16cc6b0a54f043300fb45
parent5a1a5814e77152bf2195f917147d5dc46f7201d7 (diff)
downloadbuildstream-d55039c33685d267fd8834ecc5d16030c1385325.tar.gz
utils.py: Add a _with_gc_disabled() decorator
This decorator can be used to wrapper any function to disable the GC for the duration of the function. At the end it will be re-enabled. This is not recursive, so only use this decorator sparingly and with care. Signed-off-by: Daniel Silverstone <daniel.silverstone@codethink.co.uk>
-rw-r--r--buildstream/utils.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/buildstream/utils.py b/buildstream/utils.py
index 844153706..a4e161ed4 100644
--- a/buildstream/utils.py
+++ b/buildstream/utils.py
@@ -23,6 +23,8 @@ Utilities
import calendar
import errno
+import functools
+import gc
import hashlib
import os
import re
@@ -1280,3 +1282,32 @@ def _search_upward_for_files(directory, filenames):
# i.e. we've reached the root of the filesystem
return None, None
directory = parent_dir
+
+
+# _with_gc_disabled()
+#
+# Decorate a function to disable the garbage collector across its execution.
+#
+# In general, disabling the garbage collector should be considered to be an
+# extreme action. Only use this in carefully selected subsets of the code
+# where we generally create a lot more objects than we throw away. For example
+# in loading the stream.
+#
+# Args:
+# func (callable): The callable to disable the GC for
+#
+# Returns:
+# (callable): The decorated callable
+#
+def _with_gc_disabled(func):
+ @functools.wraps(func)
+ def _gc_disabled(*args, **kwargs):
+ try:
+ gc.disable()
+ return func(*args, **kwargs)
+ finally:
+ gc.enable()
+ # Clean up to ensure we don't grow any more, freeing up room to be
+ # used by other objects during the course of running BuildStream.
+ gc.collect()
+ return _gc_disabled