devblog
This commit is contained in:
parent
8aab9bd324
commit
c90a77c464
1 changed files with 44 additions and 0 deletions
44
doc/devblog/day_286-287__rotten_locks.mdwn
Normal file
44
doc/devblog/day_286-287__rotten_locks.mdwn
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
There's something rotten in POSIX fctnl locking. It's not composable,
|
||||||
|
or thread-safe.
|
||||||
|
|
||||||
|
The most obvious problem with it is that if you have 2 threads, and they
|
||||||
|
both try to take an exclusive lock of the same file (each opening it
|
||||||
|
separately) ... They'll both succeed. Unlike 2 separate processes,
|
||||||
|
where only one can take the lock.
|
||||||
|
|
||||||
|
Then the really crazy bit: If a process has a lock file open and fcntl
|
||||||
|
locked, and then the same process opens the lock file again, for any
|
||||||
|
reason, closing the new FD will release the lock that was set
|
||||||
|
using the other FD.
|
||||||
|
|
||||||
|
So, that's a massive gotcha if you're writing complex multithreaded code.
|
||||||
|
Or generally for composition of code. Of course, C programmers deal with
|
||||||
|
this kind of thing all the time, but in the clean world of Haskell, this is
|
||||||
|
a glaring problem. We don't expect to need to worry about this kind of
|
||||||
|
unrelated side effect that breaks composition and thread safety.
|
||||||
|
|
||||||
|
After noticing this problem affected git-anenx in at least one place,
|
||||||
|
I have to assume there could be more. And I don't want to need to worry
|
||||||
|
about this problem forever. So, I have been working today on a clean fix
|
||||||
|
that I can cleanly switch all my lock-related code to use.
|
||||||
|
|
||||||
|
One reasonable approach would be to avoid fcntl locking, and use flock.
|
||||||
|
But, flock works even less well on NFS than fcntl, and git-annex relies on
|
||||||
|
some fcntl locking features. On Linux, there's an "open file description
|
||||||
|
locks" feature that fixes POSIX fnctl locking to not have this horrible
|
||||||
|
wart, but that's not portable.
|
||||||
|
|
||||||
|
Instead, my approach is to keep track of which files the process has
|
||||||
|
locked. If it tries to do something with a lockfile that it already has
|
||||||
|
locked, it avoids opening the same file again, instead implements its own
|
||||||
|
in-process locking behavior. I use STM to do that in a thread-safe manner.
|
||||||
|
|
||||||
|
I should probably break out git-annex's lock file handling code as a
|
||||||
|
library. Eventually.. This was about as much fun as a root canal, and I'm
|
||||||
|
having a real one tomorrow. :-/
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
git-annex is now included in [Stackage](http://www.stackage.org/)!
|
||||||
|
|
||||||
|
Daniel Kahn Gillmor is doing some work on reproducible builds of git-annex.
|
Loading…
Reference in a new issue