Skip to content

Commit

Permalink
utils: add simple locking primitive
Browse files Browse the repository at this point in the history
Standard python locking modules do not provide detection if lock-holding
process is still alive. Add a simple wrapper around fcntl.lockf that do
just that.
  • Loading branch information
marmarek committed Aug 4, 2020
1 parent 6338b93 commit 81559d1
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions qubesadmin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#

"""Various utility functions."""

import fcntl
import os
import re

Expand Down Expand Up @@ -164,3 +166,29 @@ def encode(part):
part = re.sub(br'[^a-zA-Z0-9_.+]', encode, arg.encode('utf-8'))
parts.append(part)
return b'+'.join(parts).decode('ascii')

class LockFile(object):
"""Simple locking context manager. It opens a file with an advisory lock
taken (fcntl.lockf)"""
def __init__(self, path, nonblock=False):
"""Open the file. Call *acquire* or enter the context to lock
the file"""
self.file = open(path, "w")
self.nonblock = nonblock

def __enter__(self, *args, **kwargs):
self.acquire()
return self

def acquire(self):
"""Lock the opened file"""
fcntl.lockf(self.file,
fcntl.LOCK_EX | (fcntl.LOCK_NB if self.nonblock else 0))

def __exit__(self, exc_type=None, exc_value=None, traceback=None):
self.release()

def release(self):
"""Unlock the file and close the file object"""
fcntl.lockf(self.file, fcntl.LOCK_UN)
self.file.close()

0 comments on commit 81559d1

Please sign in to comment.