baseimage-tutorial-framework/tfw/internals/ref_counter/ref_counter.py

46 lines
1.2 KiB
Python

from os import remove
from contextlib import contextmanager
from fcntl import flock, LOCK_EX, LOCK_UN
class RefCounter:
def __init__(self, lockpath):
self.lockpath = lockpath
self._lockfile = open(self.lockpath, 'a+')
with self.locked():
counter = self._read_counter()
self._write_counter(counter+1)
@contextmanager
def locked(self):
flock(self._lockfile, LOCK_EX)
yield
flock(self._lockfile, LOCK_UN)
def _read_counter(self):
self._lockfile.seek(0)
try:
counter = int(self._lockfile.read())
except ValueError:
counter = 0
return counter
def _write_counter(self, counter):
self._lockfile.seek(0)
self._lockfile.truncate()
self._lockfile.write(str(counter))
self._lockfile.flush()
def teardown_instance(self):
with self.locked():
counter = self._read_counter()
if counter <= 1:
remove(self.lockpath)
self.deallocate()
else:
self._write_counter(counter-1)
self._lockfile.close()
def deallocate(self):
pass