(cvs.info.gz) Locks
Info Catalog
(cvs.info.gz) CVS in repository
(cvs.info.gz) Repository storage
(cvs.info.gz) CVSROOT storage
2.2.6 CVS locks in the repository
---------------------------------
For an introduction to CVS locks focusing on user-visible behavior, see
Concurrency. 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.
Info Catalog
(cvs.info.gz) CVS in repository
(cvs.info.gz) Repository storage
(cvs.info.gz) CVSROOT storage
automatically generated byinfo2html