From Cyrus
Racefree Locking
Executive Summary
- Current cyrus locking is broken - no lock is unbreakable, so race conditions have to be worked around.
- The solution is a single lock file that never gets rewritten, so doesn't have the locking broken.
Implementation
- Create a new file: cyrus.lock.
- Lock cyrus.lock in SHARED mode whenever you have the mailbox open.
- exclusive lock on cyrus.index when you make index changes (including writing cache records for appends)
- exclusive lock on cyrus.header only when changing userflags or ACLs, etc.
- Lock cyrus.lock in EXCLUSIVE mode whenever you rewrite cyrus.index (e.g. cyr_expire)
- POP lock shouldn't be needed any more, because a SHARED lock will ensure all remembered offsets into the cyrus.index are still valid.
That's about it really. By taking a shared lock on cyrus.lock, any process can take offsets into the index_base map without worrying about it every needing to be updated.