[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2.6 CVS locks in the repository

For an introduction to CVS locks focusing on user-visible behavior, see Several developers simultaneously attempting to run CVS. The following section is aimed at people who are writing tools which want to access a CVS repository without interfering with other tools accessing the same repository. If you find yourself confused by concepts described here, like read lock, write lock, and deadlock, you might consult the literature on operating systems or databases.

Any file in the repository with a name starting with `#cvs.rfl.' is a read lock. Any file in the repository with a name starting with `#cvs.pfl' is a promotable read lock. Any file in the repository with a name starting with `#cvs.wfl' is a write lock. Old versions of CVS (before CVS 1.5) also created files with names starting with `#cvs.tfl', but they are not discussed here. The directory `#cvs.lock' serves as a master lock. That is, one must obtain this lock first before creating any of the other locks.

To obtain a read lock, first create the `#cvs.lock' directory. This operation must be atomic (which should be true for creating a directory under most operating systems). If it fails because the directory already existed, wait for a while and try again. After obtaining the `#cvs.lock' lock, create a file whose name is `#cvs.rfl.' followed by information of your choice (for example, hostname and process identification number). Then remove the `#cvs.lock' directory to release the master lock. Then proceed with reading the repository. When you are done, remove the `#cvs.rfl' file to release the read lock.

Promotable read locks are a concept you may not find in other literature on concurrency. They are used to allow a two (or more) pass process to only lock a file for read on the first (read) pass(es), then upgrade its read locks to write locks if necessary for a final pass, still assured that the files have not changed since they were first read. CVS uses promotable read locks, for example, to prevent commit and tag verification passes from interfering with other reading processes. It can then lock only a single directory at a time for write during the write pass.

To obtain a promotable read lock, first create the `#cvs.lock' directory, as with a non-promotable read lock. Then check that there are no files that start with `#cvs.pfl'. If there are, remove the master `#cvs.lock' directory, wait awhile (CVS waits 30 seconds between lock attempts), and try again. If there are no other promotable locks, go ahead and create a file whose name is `#cvs.pfl' followed by information of your choice (for example, CVS uses its hostname and the process identification number of the CVS server process creating the lock). If versions of CVS older than version 1.12.4 access your repository directly (not via a CVS server of version 1.12.4 or later), then you should also create a read lock since older versions of CVS will ignore the promotable lock when attempting to create their own write lock. Then remove the master `#cvs.lock' directory in order to allow other processes to obtain read locks.

To obtain a write lock, first create the `#cvs.lock' directory, as with read locks. Then check that there are no files whose names start with `#cvs.rfl.' and no files whose names start with `#cvs.pfl' that are not owned by the process attempting to get the write lock. If either exist, remove `#cvs.lock', wait for a while, and try again. If there are no readers or promotable locks from other processes, then create a file whose name is `#cvs.wfl' followed by information of your choice (again, CVS uses the hostname and server process identification number). Remove your `#cvs.pfl' file if present. Hang on to the `#cvs.lock' lock. Proceed with writing the repository. When you are done, first remove the `#cvs.wfl' file and then the `#cvs.lock' directory. Note that unlike the `#cvs.rfl' file, the `#cvs.wfl' file is just informational; it has no effect on the locking operation beyond what is provided by holding on to the `#cvs.lock' lock itself.

Note that each lock (write lock or read lock) only locks a single directory in the repository, including `Attic' and `CVS' but not including subdirectories which represent other directories under version control. To lock an entire tree, you need to lock each directory (note that if you fail to obtain any lock you need, you must release the whole tree before waiting and trying again, to avoid deadlocks).

Note also that CVS expects write locks to control access to individual `foo,v' files. RCS has a scheme where the `,foo,' file serves as a lock, but CVS does not implement it and so taking out a CVS write lock is recommended. See the comments at rcs_internal_lockfile in the CVS source code for further discussion/rationale.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on September, 14 2007 using texi2html 1.76.