python-liblockfile
python-liblockfile is a wrapper around liblockfile. It uses ctypes
but unfortunately has to hard-code some constants from lockfile.h, though
I’ll bet they’re fairly unlikely to change any time soon. It has tests!
Install it from PyPI: pip install python-liblockfile
There is a low-level API that mirrors liblockfile: lockfile_create,
lockfile_remove, lockfile_touch, and lockfile_check. However, for all of
these except lockfile_check it uses ctypes’ errcheck feature to raise
exceptions when the return is non-zero:
NameTooLongError- Recipient name too long.
TempLockError- Error creating tmp lockfile.
TempLockWriteError- Can't write pid into tmp lockfile.
MaxAttemptsError- Failed after max. number of attempts.
UnknownError- Unknown error; check errno.
MandatoryLockError- Cannot set mandatory lock on tempfile.
There’s also a more Pythonic, higher-level API: Lock and LockHolder. The
former encapsulates the lower-level API and also works as a context manager.
The latter is meant to be used as a context manager too, and it works with the
time-out feature of liblockfile by spawning a daemon thread to periodically
touch a lock. Here’s how you might use both together:
from liblockfile import Lock, LockHolder
with Lock("filename-to-lock") as lock, LockHolder(lock):
# ... do things that require the lock to be held.
Lock has two other constructors: WithPID and WithPPID. See the docs for
L_PID in lockfile_create(3); L_PPID can be extrapolated
from that.
If you don’t need compatibility with liblockfile then you’ll probably be
better off using a pure-Python locking library — lockfile for example — to
avoid native dependencies. This library might still be interesting as a small
piece of example code for using ctypes; it’s by no means exhaustive, and might
get things wrong, but I am open to criticism and patches.