# db_lock

           #include <db.h>

           int
           lock_open(const char *dir,
                u_int32_t flags, int mode, DB_ENV *dbenv, DB_LOCKTAB **regionp);

           int
           lock_id(DB_LOCKTAB *lt, u_int32_t *idp);

           int
           lock_vec(DB_LOCKTAB *lt, u_int32_t locker, u_int32_t flags,
                DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp);

           int
           lock_get(DB_LOCKTAB *lt, u_int32_t locker, u_int32_t flags,
                const DBT *obj, const db_lockmode_t lock_mode, DB_LOCK *lock);

           int
           lock_put(DB_LOCKTAB *lt, DB_LOCK lock);

           int
           lock_close(DB_LOCKTAB *lt);

           int
           lock_unlink(const char *dir, int force, DB_ENV *dbenv);

           int
           lock_detect(DB_LOCKTAB *lt, u_int32_t flags, u_int32_t atype);

           int
           lock_stat(DB_LOCKTAB *lt,
                DB_LOCK_STAT **spp, void *(*db_malloc)(size_t));

## DESCRIPTION

           The  DB  library  is  a family of groups of functions that
           provides a modular programming interface  to  transactions
           and  record-oriented  file  access.   The library includes
           support for transactions, locking, logging and  file  page
           caching,  as well as various indexed access methods.  Many
           of the functional groups  (e.g.,  the  file  page  caching
           functions)   are   useful  independent  of  the  other  DB
           functions, although some functional groups are  explicitly
           based  on  other functional groups (e.g., transactions and
           logging).  For a general description of  the  DB  package,
           see db_intro(3).

           This  manual  page  describes  the specific details of the
           locking interface.

           The db_lock functions are the library  interface  intended
           to  provide  general-purpose  locking.   While designed to
           work with the other DB functions, these functions are also
           useful  for  more  general locking purposes.  Locks can be
           shared between processes.  In most  cases,  when  multiple
           threads  or  processes  are  using  locking,  the deadlock
           detector, db_deadlock(1), should be run.

      lock_open
           The lock_open function copies a pointer, to the lock table
           identified  by the directory dir, into the memory location
           referenced by regionp.

           If the dbenv argument to lock_open was  initialized  using
           db_appinit,   dir   is   interpreted   as   described   by
           db_appinit(3).

           Otherwise, if dir is not NULL, it is interpreted  relative
           to  the  current working directory of the process.  If dir
           is NULL, the following environment variables  are  checked
           in  order:  ``TMPDIR'',  ``TEMP'', and ``TMP''.  If one of
           them is set, lock table files are created relative to  the
           directory  it  specifies.   If  none  of them are set, the
           first possible one of the following directories  is  used:
           /var/tmp, /usr/tmp, /temp, /tmp, C:/temp and C:/tmp.

           All  files  associated  with the lock table are created in
           this directory.  This directory must already exist when

           lock table_open is called.   If  the  lock  table  already
           exists, the process must have permission to read and write
           the existing files.  If the lock table  does  not  already
           exist, it is optionally created and initialized.

           The  flags  and  mode  arguments specify how files will be
           opened and/or created when they don't already exist.   The
           flags value is specified by or'ing together one or more of
           the following values:

           DB_CREATE
                Create any underlying files, as  necessary.   If  the
                files  do not already exist and the DB_CREATE flag is
                not specified, the call will fail.

           DB_THREAD
                Cause the DB_LOCKTAB handle returned by the lock_open
                function  to  be useable by multiple threads within a
                single address space, i.e., to be  ``free-threaded''.

           All  files  created by the lock subsystem are created with
           mode mode (as described in chmod(2)) and modified  by  the
           process'   umask  value  at  the  time  of  creation  (see
           umask(2)).  The group ownership of created files is  based
           on  the  system and directory defaults, and is not further
           specified by DB.

           The locking subsystem is configured  based  on  the  dbenv
           argument  to  lock_open, which is a pointer to a structure
           of type DB_ENV (typedef'd in <db.h>).   Applications  will
           normally  use  the  same  DB_ENV structure (initialized by
           db_appinit(3)), as an argument to all of the subsystems in
           the DB package.

           References  to  the DB_ENV structure are maintained by DB,
           so it may not be discarded until the last close  function,
           corresponding  to  an  open  function  for which it was an
           argument, has returned.  In order to ensure  compatibility
           with  future  releases  of  DB,  all  fields of the DB_ENV
           structure  that  are  not   explicitly   set   should   be
           initialized  to  0  before the first time the structure is
           used.  Do this by  declaring  the  structure  external  or
           static,  or  by  calling the C library routine bzero(3) or
           memset(3).

           The fields of the DB_ENV structure used by  lock_open  are
           described  below.   If  dbenv is NULL or any of its fields
           are set to 0, defaults appropriate for the system are used
           where possible.

           The  following  fields  in  the  DB_ENV  structure  may be
           initialized before calling lock_open:

           void *(*db_errcall)(char *db_errpfx, char *buffer);
           FILE *db_errfile;
           const char *db_errpfx;
           int db_verbose;
                The error fields of the DB_ENV  behave  as  described
                for db_appinit(3).

           const u_int8_t lk_conflicts[][];
                A  lk_modes by lk_modes array.  A non-0 value for the
                array element:

                     lk_conflicts[requested_mode][held_mode]

                indicates that requested_mode and held_mode conflict.
                The  ``not-granted''  mode  must be represented by 0.
                If  lk_conflicts  is  NULL,   the   conflicts   array
                db_rw_conflicts   is  used;  see  the  section  below
                entitled ``STANDARD LOCK MODES'' for a description of
                that array.

           db_detect_t lk_detect;
                If non-0, specifies that the deadlock detector be run
                whenever a lock conflict occurs, and specifies  which
                transaction  should  be  aborted  in  the  case  of a
                deadlock.  The lk_detect field must be set to one  of
                the following values.

                DB_LOCK_DEFAULT
                     Use  the  default  policy  as  specified  in the
                     db_deadlock(1) man page.

                DB_LOCK_OLDEST
                     Abort the oldest transaction.

                DB_LOCK_RANDOM
                     Abort  a  random  transaction  involved  in  the
                     deadlock.

                DB_LOCK_YOUNGEST
                     Abort the youngest transaction.

           u_int32_t lk_max;
                The  maximum  number of locks to be held or requested
                in the table.  This value is  used  by  lock_open  to
                estimate how much space to allocate for various lock-
                table data structures.  If lk_max  is  0,  a  default
                value is used.

           u_int32_t lk_modes;
                The number of lock modes to be recognized by the lock
                table  (including  the  ``not-granted''  mode).    If
                lk_modes  is  0,  the value DB_LOCK_RW_N is used; see
                below for a description of that value.

           The lock_open function  returns  the  value  of  errno  on
           failure and 0 on success.

      lock_id
           The   lock_id  function  copies  a  locker  ID,  which  is
           guaranteed to be unique in the specified lock table,  into
           the memory location referenced by idp.

           The  access  methods  (see  db_open(3)), generate a unique
           locker ID for each  file  that  is  opened  with  locking.
           During  DB access method operation, this locker ID will be
           used for all lock calls unless  a  transaction  identifier
           was  specified for the call, in which case the transaction
           ID specified is used for locking.

           The lock_id function returns the value of errno on failure
           and 0 on success.

      lock_vec
           The  lock_vec function atomically obtains and releases one
           or more locks from the specified table, lt.  The  lock_vec
           function  is intended to support acquisition or trading of
           multiple locks under  one  lock  table  semaphore,  as  is
           needed  for  lock  coupling or in multigranularity locking
           for lock escalation.

           The locker argument specified to lock_vec is  an  unsigned
           32-bit   integer   quantity.   It  represents  the  entity
           requesting or releasing the lock.

           The flags value must be set to 0 or the following value:

           DB_LOCK_NOWAIT
                If a lock cannot be  granted  because  the  requested
                lock   conflicts   with   an  existing  lock,  return
                immediately instead of waiting for the lock to become
                available.

           The list array provided to lock_vec is typedef'd in <db.h>
           as DB_LOCKREQ.  A DB_LOCKREQ structure has  at  least  the
           following fields, which must be initialized before calling
           lock_vec:

           lockop_t op;
                The operation to be performed, which must be  set  to
                one of the following values:

                DB_LOCK_GET
                     Get  a lock, as defined by the values of locker,
                     obj and mode.  Upon return from lock_vec, if the
                     lock  field  is  non-NULL,  a  reference  to the
                     acquired lock is stored there.  (This  reference
                     is  invalidated  by  any  call  to  lock_vec  or
                     lock_put that releases the lock.)

                DB_LOCK_PUT
                     The lock referenced by the contents of the  lock
                     field is released.

                DB_LOCK_PUT_ALL
                     All locks held by the locker are released.  (Any
                     locks acquired as a part of the current call  to
                     lock_vec  that  appear after the DB_LOCK_PUT_ALL
                     entry are not considered for this operation).

                DB_LOCK_PUT_OBJ
                     All locks held by the locker, on the object obj,
                     with   the  mode  specified  by  lock_mode,  are
                     released.  A lock_mode of  DB_LOCK_NG  indicates
                     that all locks on the object should be released.
                     Note that any locks acquired as a  part  of  the
                     current  call  to lock_vec that occur before the
                     DB_LOCK_PUT_OBJ will  also  be  released;  those
                     acquired afterwards will not be released.

           const DBT obj;
                An  untyped  byte string that specifies the object to
                be locked or released.

           const lockmode_t mode;
                The lock mode, used as an index  into  lt's  conflict
                array.

           DB_LOCK lock;
                A lock reference.

           The nlist argument specifies the number of elements in the
           list array.

           If any of the requested locks cannot be acquired,  or  any
           of  the  locks  to  be  released  cannot  be released, the
           operations before the failing operation are guaranteed  to
           have  completed  successfully, and lock_vec returns a non-
           zero value.  In addition, if elistp is not NULL, it is set
           to  point to the DB_LOCKREQ entry that was being processed
           when the error occurred.

           In the case of an error, lock_vec may return  one  of  the
           following values:

           DB_LOCK_DEADLOCK
                The  specified  locker  was  selected  as a victim in
                order to resolve a deadlock.

           DB_LOCK_NOTHELD
                The lock cannot be released, as it was  not  held  by
                the locker.

           DB_LOCK_NOTGRANTED
                A  lock  was  requested that could not be granted and
                the flag parameter was  set  to  DB_LOCK_NOWAIT.   In
                this case, if non-NULL, elistp identifies the request
                that was granted.

           Otherwise, the lock_vec  function  returns  the  value  of
           errno on failure and 0 on success.

      lock_get
           The  lock_get  function  is  a  simple  interface  to  the
           lock_vec functionality, and is equivalent to  calling  the
           lock_vec function with the lt and locker arguments, elistp
           and conflict arguments, and a single element  list  array,
           for  which  the  op  field  is  DB_LOCK_GET,  and the obj,
           lock_mode and lock fields are represented by the arguments
           of  the same name.  Note that the type of the obj argument
           to lock_get is different from the obj element found in the
           DB_LOCKREQ   structure.   The  lock_get  function  returns
           success  and  failure  as  described  for   the   lock_vec
           function.

      lock_put
           The  lock_put  function  is  a  simple  interface  to  the
           lock_vec functionality, and is equivalent to  calling  the
           lock_vec  function  with  a single element list array, for
           which the op field is DB_LOCK_PUT and the  lock  field  is
           represented  by  the  argument  of  the  same  name.   The
           lock_put function returns success and failure as described
           for the lock_vec function.

      lock_close
           The  lock_close function disassociates the calling process
           from the lock table lt.  Note  that  lock_close  does  not
           release  any  locks  still  held  by  the closing process.
           (This  provides  functionality  for   long-lived   locks.)
           Processes  that  wish to have all their locks released can
           do so by issuing the appropriate lock_vec call.

           In addition, if the dir argument to lock_open was NULL and
           dbenv  was  not  initialized  using  db_appinit, all files
           created for this shared region  will  be  removed,  as  if
           lock_unlink were called.

           When  multiple  threads  are  using  the DB_LOCKTAB handle
           concurrently, only a single thread may call the lock_close
           function.

           The  lock_close  function  returns  the  value of errno on
           failure and 0 on success.

      lock_unlink
           The  lock_unlink  function   destroys   the   lock   table
           identified  by  the directory dir, removing all files used
           to implement the lock table.  (The directory  dir  is  not
           removed.)    If  there  are  processes  that  have  called
           lock_open without  calling  lock_close  (i.e.,  there  are
           processes  currently  using  the  lock table), lock_unlink
           will fail without further action, unless the force flag is
           set,  in which case lock_unlink will attempt to remove the
           lock table files regardless of any processes  still  using
           the lock table.

           The  result  of  attempting to forcibly destroy the region
           when  a  process  has  the  region  open  is  unspecified.
           Processes  using  a  shared memory region maintain an open
           file descriptor for  it.   On  UNIX  systems,  the  region
           removal  should  succeed  and  processes that have already
           joined the region should continue to  run  in  the  region
           without  change,  however processes attempting to join the
           lock table will either fail or attempt  to  create  a  new
           region.   On other systems, e.g., WNT, where the unlink(2)
           system call will fail if any  process  has  an  open  file
           descriptor for the file, the region removal will fail.

           In  the  case  of catastrophic or system failure, database
           recovery must  be  performed  (see  db_recover(1)  or  the
           DB_RECOVER  and  DB_RECOVER_FATAL flags to db_appinit(3)).
           Alternatively, if recovery  is  not  required  because  no
           database  state  is  maintained  across  failures,  it  is
           possible to clean up a lock table by removing all  of  the
           files   in   the  directory  specified  to  the  lock_open
           function, as lock table files are  never  created  in  any
           directory  other  than  the  one  specified  to lock_open.
           Note, however, that this has the potential to remove files
           created  by  the  other  DB  subsystems  in  this database
           environment.

           The lock_unlink function returns the  value  of  errno  on
           failure and 0 on success.

      lock_detect
           The   lock_detect  function  runs  one  iteration  of  the
           deadlock  detector  on  the  specified  table,  lt.    The
           deadlock   detector  traverses  the  lock  table,  detects
           deadlocks,  and  if  it  finds  one,  marks  one  of   the
           participating transactions for abort and then returns.

           The  flags  value  is  specified by or'ing together one or
           more of the following values:

           DB_LOCK_CONFLICT
                Only run the deadlock detector if a lock conflict has
                occurred  since  the  last  time  that  the  deadlock
                detector was run.

           The atype parameter specifies which transaction  to  abort
           in  the case of deadlock.  It must be set to one of values
           described above for the  lk_detect  field  of  the  DB_ENV
           structure.

           The  lock_detect  function  returns  the value of errno on
           failure and 0 on success.

           The lock_detect function is the underlying  function  used
           by  the  db_deadlock(1)  utility.  See the source code for
           the  db_deadlock  utility  for   an   example   of   using
           lock_detect in a UNIX environment.

      lock_stat
           The lock_stat function creates a statistical structure and
           copies a pointer to  it  into  the  user-specified  memory
           location.

           Statistical structure are created in allocated memory.  If
           db_malloc is  non-NULL,  it  is  called  to  allocate  the
           memory, otherwise, the library function malloc(3) is used.
           The function db_malloc must match the calling  conventions
           of  the malloc(3) library routine.  Regardless, the caller
           is responsible for deallocating the returned  memory.   To
           deallocate  the returned memory, free each returned memory
           pointer; pointers inside the memory  do  not  need  to  be
           individually freed.
           The  lock  region  statistics are stored in a structure of
           type DB_LOCK_STAT (typedef'd in  <db.h>).   The  following
           DB_LOCK_STAT fields will be filled in:

           u_int32_t st_magic;
                The  magic  number  that  identifies a file as a lock
                file.
           u_int32_t st_version;
                The version of the lock file type.
           u_int32_t st_refcnt;
                The number of references to the region.
           u_int32_t st_regsize;
                The size of the region.
           u_int32_t st_maxlocks;
                The maximum number of locks possible.
           u_int32_t st_nmodes;
                The number of lock modes.
           u_int32_t st_numobjs;
                The number of unique objects locked.
           u_int32_t st_nlockers;
                The number of unique lockers.
           u_int32_t st_nconflicts;
                The total number of locks not  immediately  available
                due to conflicts.
           u_int32_t st_nrequests;
                The total number of locks requested.
           u_int32_t st_nreleases;
                The total number of locks released.
           u_int32_t st_ndeadlocks
                The number of deadlocks detected.
           u_int32_t st_region_wait;
                The  number  of  times  that  a thread of control was
                forced to wait before obtaining the region lock.
           u_int32_t st_region_nowait;
                The number of times that a thread of control was able
                to obtain the region lock without waiting.

## ENVIRONMENT VARIABLES

           The  following  environment variables affect the execution
           of db_lock:

           DB_HOME
                If the dbenv argument to  lock_open  was  initialized
                using  db_appinit,  the  environment variable DB_HOME
                may be used as the path of the database home for  the
                interpretation  of  the dir argument to lock_open, as
                described in db_appinit(3).

           TMPDIR
                If the dbenv argument to lock_open was  NULL  or  not
                initialized   using   db_appinit,   the   environment
                variable TMPDIR may be used as the directory in which
                to  create  the  lock  table,  as  described  in  the
                lock_open section above.

## STANDARD LOCK MODES

           The  include  file  <db.h>  declares  two  commonly   used
           conflict arrays:

           const u_int8_t db_lock_rw_conflicts[];
                This  is  a  conflict array for a simple scheme using
                shared and exclusive lock modes.

           const u_int8_t db_lock_riw_conflicts[];
                This is a conflict array that involves various intent
                lock  modes  (e.g.,  intent shared) that are used for
                multigranularity locking.

           Their associated sizes are DB_LOCK_RW_N and DB_LOCK_RIW_N.

           In  addition,  the  include  file  <db.h> defines the type
           db_lockmode_t, which is the type of the  lock  modes  used
           with the standard tables above:

                  DB_LOCK_NG
                       not granted (always 0)

                  DB_LOCK_READ
                       read (shared)

                  DB_LOCK_WRITE
                       write (exclusive)

## ERRORS

           The  lock_open  function may fail and return errno for any
           of the errors specified for the following DB  and  library
           functions: close(2), db_version(3), fcntl(2), fflush(3),
           lock_unlink(3), lseek(2), malloc(3), memcpy(3), memset(3),
           mmap(2), munmap(2), open(2), sigfillset(3),
           sigprocmask(2), stat(2), strcpy(3), strdup(3),
           strerror(3), strlen(3), unlink(2), and write(2).

           In  addition,  the  lock_open function may fail and return
           errno for the following conditions:

           [EAGAIN]
                The shared memory region was locked and  (repeatedly)
                unavailable.

           [EINVAL]
                An invalid flag value or parameter was specified.

                The  DB_THREAD  flag  was specified and spinlocks are
                not implemented for this architecture.

           The lock_vec function may fail and return errno for any of
           the  errors  specified  for  the  following DB and library
           functions: fcntl(2), fflush(3), lock_detect(3), lseek(2),
           memcpy(3), memset(3), mmap(2), munmap(2), strerror(3), and
           write(2).

           In addition, the lock_vec function  may  fail  and  return
           errno for the following conditions:

           [EACCES]
                An  attempt  was made to release lock held by another
                locker.

           [EINVAL]
                An invalid flag value or parameter was specified.

           The lock_get function may fail and return errno for any of
           the  errors  specified  for  the  following DB and library
           functions: fcntl(2), fflush(3), lock_detect(3), lseek(2),
           memcpy(3), memset(3), mmap(2), munmap(2), strerror(3), and
           write(2).

           In addition, the lock_get function  may  fail  and  return
           errno for the following conditions:

           [EINVAL]
                An invalid flag value or parameter was specified.

           The lock_put function may fail and return errno for any of
           the errors specified for  the  following  DB  and  library
           functions: fcntl(2), fflush(3), lock_detect(3), lseek(2),
           memcpy(3), memset(3), mmap(2), munmap(2), strerror(3), and
           write(2).

           In  addition,  the  lock_put  function may fail and return
           errno for the following conditions:

           [EACCES]
                An attempt was made to release lock held  by  another
                locker.

           [EINVAL]
                An invalid flag value or parameter was specified.

           The  lock_close function may fail and return errno for any
           of the errors specified for the following DB  and  library
           functions: close(2), fcntl(2), fflush(3), munmap(2), and
           strerror(3).

           The lock_unlink function may fail and return errno for any
           of  the  errors specified for the following DB and library
           functions: close(2), fcntl(2), fflush(3), malloc(3),
           memcpy(3), memset(3), mmap(2), munmap(2), open(2),
           sigfillset(3), sigprocmask(2), stat(2), strcpy(3),
           strdup(3), strerror(3), strlen(3), and unlink(2).

           In  addition, the lock_unlink function may fail and return
           errno for the following conditions:

           [EBUSY]
                The shared memory region was in  use  and  the  force
                flag was not set.

           The lock_detect function may fail and return errno for any
           of the errors specified for the following DB  and  library
           functions: calloc(3), fcntl(2), fflush(3), lseek(2),
           malloc(3), memcpy(3), memset(3), mmap(2), munmap(2),
           strerror(3), and write(2).

## BUGS

           If  a process dies while holding locks, those locks remain
           held and are never released.  In this case, all  processes
           should exit as quickly as possible, so that db_recover can
           be run.

## SEE ALSO

           db_archive(1), db_checkpoint(1), db_deadlock(1), db_dump(1),
           db_load(1), db_recover(1), db_stat(1), db_intro(3),
           db_appinit(3), db_cursor(3), db_dbm(3), db_internal(3),
           db_lock(3), db_log(3), db_mpool(3), db_open(3), db_thread(3),
           db_txn(3)