source: trunk/src/allmydata/util/gcutil.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 2.3 KB
Line 
1"""
2Helpers for managing garbage collection.
3
4:ivar fileDescriptorResource: A garbage-collection-informing resource tracker
5    for file descriptors.  This is used to trigger a garbage collection when
6    it may be possible to reclaim a significant number of file descriptors as
7    a result.  Register allocation and release of *bare* file descriptors with
8    this object (file objects, socket objects, etc, have their own integration
9    with the garbage collector and don't need to bother with this).
10
11Ported to Python 3.
12"""
13
14__all__ = [
15    "fileDescriptorResource",
16]
17
18import gc
19
20import attr
21
22@attr.s
23class _ResourceTracker(object):
24    """
25    Keep track of some kind of resource and trigger a full garbage collection
26    when allocations outnumber releases by some amount.
27
28    :ivar int _counter: The number of allocations that have happened in excess
29        of releases since the last full collection triggered by this tracker.
30
31    :ivar int _threshold: The number of excess allocations at which point a
32        full collection will be triggered.
33    """
34    _counter = attr.ib(default=0)
35    _threshold = attr.ib(default=25)
36
37    def allocate(self):
38        """
39        Register the allocation of an instance of this resource.
40        """
41        self._counter += 1
42        if self._counter > self._threshold:
43            gc.collect()
44            # Garbage collection of this resource has done what it can do.  If
45            # nothing was collected, it doesn't make any sense to trigger
46            # another full collection the very next time the resource is
47            # allocated.  Start the counter over again.  The next collection
48            # happens when we again exceed the threshold.
49            self._counter = 0
50
51
52    def release(self):
53        """
54        Register the release of an instance of this resource.
55        """
56        if self._counter > 0:
57            # If there were any excess allocations at this point, account for
58            # there now being one fewer.  It is not helpful to allow the
59            # counter to go below zero (as naturally would if a collection is
60            # triggered and then subsequently resources are released).  In
61            # that case, we would be operating as if we had set a higher
62            # threshold and that is not desired.
63            self._counter -= 1
64
65fileDescriptorResource = _ResourceTracker()
Note: See TracBrowser for help on using the repository browser.