Introduce finalizer module to manage finalization of C resources.
This commit is contained in:
parent
e8c7fcfd32
commit
bc20661343
7 changed files with 110 additions and 40 deletions
58
llvm/_utils/finalizer.py
Normal file
58
llvm/_utils/finalizer.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
'''
|
||||
Modified C-level finalizer by Benjamin Peterson <benjamin@python.org>
|
||||
Available at http://code.activestate.com/recipes/577242-calling-c-level-finalizers-without-__del__/
|
||||
'''
|
||||
import sys
|
||||
import traceback
|
||||
import weakref
|
||||
|
||||
class OwnerRef(weakref.ref):
|
||||
"""A simple weakref.ref subclass, so attributes can be added."""
|
||||
pass
|
||||
|
||||
def _run_finalizer(ref):
|
||||
"""Internal weakref callback to run finalizers"""
|
||||
del _finalize_refs[ref.owner]
|
||||
for item, finalizer in ref.items:
|
||||
try:
|
||||
finalizer(item)
|
||||
except Exception:
|
||||
print>>sys.stderr, "Exception running {}:".format(finalizer)
|
||||
traceback.print_exc()
|
||||
|
||||
_finalize_refs = {}
|
||||
|
||||
def track(owner, item, finalizer):
|
||||
"""Register an object for finalization.
|
||||
|
||||
``owner`` is the the object which is responsible for ``item``.
|
||||
``finalizer`` will be called with ``item`` as its only argument when
|
||||
``owner`` is destroyed by the garbage collector.
|
||||
"""
|
||||
if id(owner) in _finalize_refs:
|
||||
ref = _finalize_refs[id(owner)]
|
||||
else:
|
||||
ref = OwnerRef(owner, _run_finalizer)
|
||||
ref.owner = id(owner)
|
||||
ref.items = []
|
||||
ref.items.append((item, finalizer))
|
||||
_finalize_refs[id(owner)] = ref
|
||||
|
||||
def untrack(owner, item):
|
||||
ref = _finalize_refs[id(owner)]
|
||||
# search and remove the item from the ref
|
||||
for i, (item_i, _) in enumerate(ref.items):
|
||||
if item_i is item:
|
||||
del ref.items[i]
|
||||
# remove the ref if it is empty
|
||||
if not ref.items:
|
||||
del _finalize_refs[id(owner)]
|
||||
|
||||
class OwnerMixin(object):
|
||||
def _finalizer_track(self, item):
|
||||
if not hasattr(self, '_finalize'):
|
||||
raise AttributeError("%s must define a _finalize method" % self)
|
||||
track(self, item, type(self)._finalize)
|
||||
|
||||
def _finalizer_untrack(self, item):
|
||||
untrack(self, item)
|
||||
Loading…
Add table
Add a link
Reference in a new issue